"การเน้น" นี้ดูเหมือนจะเกิดขึ้นมากมายและฉันสงสัยว่านี่เป็นข้อกำหนดในภาษา Python หรือเป็นเพียงเรื่องของการประชุม?
นอกจากนี้คนชื่อและอธิบายฟังก์ชั่นที่มีแนวโน้มที่จะมีขีดล่างและทำไม ( __init__
เช่น)?
"การเน้น" นี้ดูเหมือนจะเกิดขึ้นมากมายและฉันสงสัยว่านี่เป็นข้อกำหนดในภาษา Python หรือเป็นเพียงเรื่องของการประชุม?
นอกจากนี้คนชื่อและอธิบายฟังก์ชั่นที่มีแนวโน้มที่จะมีขีดล่างและทำไม ( __init__
เช่น)?
คำตอบ:
จากPython PEP 8 - คู่มือสไตล์สำหรับ Python Code :
อธิบาย: รูปแบบการตั้งชื่อ
รูปแบบพิเศษต่อไปนี้ที่ใช้ขีดเส้นใต้หรือขีดล่างได้รับการยอมรับ (โดยทั่วไปสามารถรวมกับการประชุมกรณีใด ๆ ):
_single_leading_underscore
: ตัวบ่งชี้ "การใช้ภายใน" อ่อน เช่นfrom M import *
ไม่นำเข้าวัตถุที่ชื่อขึ้นต้นด้วยเครื่องหมายขีดล่าง
single_trailing_underscore_
: ใช้โดยการประชุมเพื่อหลีกเลี่ยงข้อขัดแย้งกับคำหลัก Python เช่น
Tkinter.Toplevel(master, class_='ClassName')
__double_leading_underscore
: เมื่อตั้งชื่อแอตทริบิวต์ class ให้เรียกใช้ชื่อ mangling (ภายในคลาส FooBar__boo
กลายเป็น_FooBar__boo
; ดูด้านล่าง)
__double_leading_and_trailing_underscore__
: วัตถุหรือแอตทริบิวต์ "เวทมนต์" ที่อาศัยอยู่ในเนมสเปซที่ผู้ใช้ควบคุม เช่น__init__
, หรือ__import__
__file__
ไม่เคยประดิษฐ์ชื่อดังกล่าว ใช้เป็นเอกสารเท่านั้น
โปรดทราบว่าชื่อที่มีเครื่องหมายขีดเส้นใต้และขีดเส้นใต้แบบคู่จะถูกสงวนไว้สำหรับ Python เป็นหลัก: "อย่าประดิษฐ์ชื่อดังกล่าวเพียงใช้มันเป็นเอกสาร"
__double_leading_underscore
ยังคงเป็นสาธารณะตัวแปรถูกเปลี่ยนชื่อเพียงเพื่อหลีกเลี่ยงการปะทะกัน
ผู้ตอบแบบสอบถามคนอื่น ๆ นั้นถูกต้องในการอธิบายการขีดเส้นใต้และขีดเส้นใต้สองครั้งเป็นแบบแผนการตั้งชื่อสำหรับวิธี "พิเศษ" หรือ "เวทมนตร์"
ในขณะที่คุณสามารถเรียกวิธีการเหล่านี้โดยตรง ( [10, 20].__len__()
ตัวอย่าง) การมีอยู่ของขีดเส้นใต้เป็นคำใบ้ว่าวิธีการเหล่านี้มีจุดประสงค์เพื่อเรียกใช้ทางอ้อม ( len([10, 20])
ตัวอย่าง) ผู้ประกอบการหลามส่วนใหญ่มีวิธี "เวทมนต์" ที่เกี่ยวข้อง (ตัวอย่างเช่นa[x]
เป็นวิธีปกติของการเรียกa.__getitem__(x)
)
ชื่อที่ล้อมรอบด้วยเครื่องหมายขีดล่างคู่เป็น "พิเศษ" ถึง Python พวกเขากำลังแสดงอยู่ในภาษา Python อ้างอิงมาตรา 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))
...
และเด็กที่มีวิธี _worker
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__
ระบุตำแหน่งของไฟล์ Python ที่__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
เพิ่มตัวอย่างเพื่อทำความเข้าใจการใช้ __ ใน python นี่คือรายการทั้งหมด __
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