这种“下划线”似乎经常出现,我想知道这是否是 Python 语言的要求,或者仅仅是约定的问题?
另外,有人可以命名并解释哪些函数倾向于带有下划线,以及为什么(__init__
例如)?
这种“下划线”似乎经常出现,我想知道这是否是 Python 语言的要求,或者仅仅是约定的问题?
另外,有人可以命名并解释哪些函数倾向于带有下划线,以及为什么(__init__
例如)?
来自Python PEP 8——Python 代码样式指南:
描述性:命名样式
识别以下使用前导或尾随下划线的特殊形式(这些通常可以与任何大小写约定结合使用):
_single_leading_underscore
:弱“内部使用”指标。例如from M import *
,不导入名称以下划线开头的对象。
single_trailing_underscore_
: 按照惯例使用以避免与 Python 关键字冲突,例如
Tkinter.Toplevel(master, class_='ClassName')
__double_leading_underscore
: 当命名一个类属性时,调用名称修饰(在类 FooBar 中,__boo
变为_FooBar__boo
; 见下文)。
__double_leading_and_trailing_underscore__
: 存在于用户控制的命名空间中的“神奇”对象或属性。例如__init__
,__import__
或__file__
。永远不要发明这样的名字;仅按记录使用它们。
请注意,带有双前导和尾随下划线的名称本质上是为 Python 本身保留的:“永远不要发明这样的名称;仅按照文档说明使用它们”。
其他受访者将双前导和尾随下划线描述为“特殊”或“魔术”方法的命名约定是正确的。
虽然您可以直接调用这些方法([10, 20].__len__()
例如),但下划线的存在暗示这些方法旨在间接调用(len([10, 20])
例如)。大多数 python 运算符都有一个关联的“魔术”方法(例如,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)
)
...
添加了一个示例来了解 __ 在 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
此约定用于特殊变量或方法(所谓的“魔术方法”),例如__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