यह "अंडरस्कोरिंग" बहुत कुछ प्रतीत होता है, और मैं सोच रहा था कि क्या पायथन भाषा में यह आवश्यकता थी, या केवल सम्मेलन की बात है?
इसके अलावा, क्या कोई व्यक्ति यह बता सकता है कि कौन से कार्य अंडरस्कोर होते हैं, और क्यों ( __init__
उदाहरण के लिए)?
यह "अंडरस्कोरिंग" बहुत कुछ प्रतीत होता है, और मैं सोच रहा था कि क्या पायथन भाषा में यह आवश्यकता थी, या केवल सम्मेलन की बात है?
इसके अलावा, क्या कोई व्यक्ति यह बता सकता है कि कौन से कार्य अंडरस्कोर होते हैं, और क्यों ( __init__
उदाहरण के लिए)?
जवाबों:
से अजगर कोड के लिए स्टाइल गाइड - अजगर पीईपी 8 :
वर्णनात्मक: नामकरण शैलियाँ
प्रमुख या अनुगामी अंडरस्कोर का उपयोग करते हुए निम्नलिखित विशेष रूपों को मान्यता दी जाती है (इन्हें आमतौर पर किसी भी मामले के सम्मेलन के साथ जोड़ा जा सकता है):
_single_leading_underscore
: कमजोर "आंतरिक उपयोग" सूचक। Egfrom M import *
उन वस्तुओं को आयात नहीं करता है जिनका नाम अंडरस्कोर से शुरू होता है।
single_trailing_underscore_
: पाइथन कीवर्ड के साथ संघर्ष से बचने के लिए सम्मेलन द्वारा उपयोग किया जाता है, जैसे
Tkinter.Toplevel(master, class_='ClassName')
__double_leading_underscore
: जब क्लास की विशेषता का नामकरण किया जाता है, तो नाम मैनलिंग (कक्षा FooBar के अंदर,__boo
बन जाता है_FooBar__boo
; नीचे देखें;) को आमंत्रित करता है ।
__double_leading_and_trailing_underscore__
: "जादू" ऑब्जेक्ट्स या विशेषताएँ जो उपयोगकर्ता-नियंत्रित नामस्थानों में रहती हैं। जैसे__init__
,__import__
या__file__
। ऐसे नामों का आविष्कार कभी न करें; केवल उन्हें प्रलेखित के रूप में उपयोग करें।
ध्यान दें कि दोहरे अग्रणी और अनुगामी अंडरस्कोर वाले नाम अनिवार्य रूप से पायथन के लिए ही आरक्षित हैं: "कभी भी ऐसे नामों का आविष्कार न करें, केवल उन्हें दस्तावेज के रूप में उपयोग करें"।
__double_leading_underscore
है अभी भी सार्वजनिक , चर बस एक टकराव से बचने के लिए नाम दिया गया है।
अन्य उत्तरदाताओं ने "विशेष" या "जादू" विधियों के लिए नामकरण सम्मेलन के रूप में दोहरे अग्रणी और अनुगामी अंडरस्कोर का वर्णन करने में सही हैं।
जब आप इन तरीकों को सीधे ( [10, 20].__len__()
उदाहरण के लिए) कह सकते हैं , तो अंडरस्कोर की उपस्थिति एक संकेत है कि इन तरीकों को अप्रत्यक्ष रूप से ( len([10, 20])
उदाहरण के लिए) लागू करने का इरादा है । अधिकांश अजगर ऑपरेटरों के पास एक संबंधित "जादू" विधि है (उदाहरण के लिए, a[x]
आह्वान करने का सामान्य तरीका a.__getitem__(x)
)।
डबल अंडरस्कोर से घिरे नाम पायथन के लिए "विशेष" हैं। वे पायथन भाषा संदर्भ, खंड 3, "डेटा मॉडल" में सूचीबद्ध हैं ।
वास्तव में जब मैं माता-पिता और बच्चे के वर्ग के नामों के बीच अंतर करने की आवश्यकता होती है तो मैं विधि नामों का उपयोग करता हूं। मैंने कुछ कोड पढ़े हैं, जो अभिभावक-बच्चे वर्ग बनाने के इस तरीके का उपयोग करते हैं। एक उदाहरण के रूप में मैं यह कोड प्रदान कर सकता हूं:
class ThreadableMixin:
def start_worker(self):
threading.Thread(target=self.worker).start()
def worker(self):
try:
self._worker()
except tornado.web.HTTPError, e:
self.set_status(e.status_code)
except:
logging.error("_worker problem", exc_info=True)
self.set_status(500)
tornado.ioloop.IOLoop.instance().add_callback(self.async_callback(self.results))
...
और बच्चे के पास एक _वर्क विधि है
class Handler(tornado.web.RequestHandler, ThreadableMixin):
def _worker(self):
self.res = self.render_string("template.html",
title = _("Title"),
data = self.application.db.query("select ... where object_id=%s", self.object_id)
)
...
इस सम्मेलन का उपयोग विशेष चर या विधियों (तथाकथित "जादू पद्धति") जैसे __init__
और के लिए किया जाता है __len__
। ये विधियाँ विशेष वाक्यात्मक विशेषताएँ प्रदान करती हैं या विशेष कार्य करती हैं।
उदाहरण के लिए, __file__
पायथन फ़ाइल के स्थान को इंगित करता है, __eq__
जब a == b
अभिव्यक्ति निष्पादित होती है तो निष्पादित किया जाता है।
एक उपयोगकर्ता निश्चित रूप से एक कस्टम विशेष विधि बना सकता है, जो बहुत ही दुर्लभ मामला है, लेकिन अक्सर कुछ अंतर्निहित विशेष विधियों को संशोधित कर सकता है (जैसे __init__
कि आपको कक्षा को इनिशियलाइज़ करना चाहिए कि पहली बार तब निष्पादित किया जाएगा जब एक कक्षा का एक उदाहरण बनाया गया है)।
class A:
def __init__(self, a): # use special method '__init__' for initializing
self.a = a
def __custom__(self): # custom special method. you might almost do not use it
pass
अजगर में __ के उपयोग को समझने के लिए एक उदाहरण जोड़ा गया। यहाँ सभी __ की सूची है
https://docs.python.org/3/genindex-all.html#_
कुछ वर्गों की पहचानकर्ता (कीवर्ड के अलावा) के विशेष अर्थ हैं। किसी भी संदर्भ में * नाम का कोई भी उपयोग , जो स्पष्ट रूप से प्रलेखित उपयोग का पालन नहीं करता है, चेतावनी के बिना टूटना के अधीन है
__ का उपयोग करके प्रतिबंध
"""
Identifiers:
- Contain only (A-z, 0-9, and _ )
- Start with a lowercase letter or _.
- Single leading _ : private
- Double leading __ : strong private
- Start & End __ : Language defined Special Name of Object/ Method
- Class names start with an uppercase letter.
-
"""
class BankAccount(object):
def __init__(self, name, money, password):
self.name = name # Public
self._money = money # Private : Package Level
self.__password = password # Super Private
def earn_money(self, amount):
self._money += amount
print("Salary Received: ", amount, " Updated Balance is: ", self._money)
def withdraw_money(self, amount):
self._money -= amount
print("Money Withdraw: ", amount, " Updated Balance is: ", self._money)
def show_balance(self):
print(" Current Balance is: ", self._money)
account = BankAccount("Hitesh", 1000, "PWD") # Object Initalization
# Method Call
account.earn_money(100)
# Show Balance
print(account.show_balance())
print("PUBLIC ACCESS:", account.name) # Public Access
# account._money is accessible because it is only hidden by convention
print("PROTECTED ACCESS:", account._money) # Protected Access
# account.__password will throw error but account._BankAccount__password will not
# because __password is super private
print("PRIVATE ACCESS:", account._BankAccount__password)
# Method Call
account.withdraw_money(200)
# Show Balance
print(account.show_balance())
# account._money is accessible because it is only hidden by convention
print(account._money) # Protected Access