为什么某些函数在函数名称前后有下划线“__”?
这似乎发生了很多,并想知道这是否是Python语言的要求,还是仅仅是一个约定的问题?
另外,有人可以命名和解释哪些函数往往有下划线,为什么( __init__
,例如)?
从Python PEP 8 – Python的风格指南代码 :
描述性:命名样式
以下特殊forms使用前置或后缀下划线(这些通常可以与任何案例惯例结合使用):
_single_leading_underscore
:弱的“内部使用”指标。 例如from M import *
不导入名称以下划线开头的对象。
single_trailing_underscore_
:single_trailing_underscore_
使用,以避免与Python关键字冲突,例如
Tkinter.Toplevel(master, class_='ClassName')
__double_leading_underscore
:命名一个类属性时,调用名字改变(在类FooBar中,__boo
变成_FooBar__boo
;见下文)。
__double_leading_and_trailing_underscore__
:位于用户控制的命名空间中的“魔术”对象或属性。 例如__init__
,__init__
__import__
或__file__
。 不要发明这样的名字; 只有按照logging使用它们。
请注意,带有双下划线和下划线下划线的名字本质上是为Python本身保留的:“永远不要发明这样的名字;只能用它们来logging”。
其他受访者将双重前后下划线描述为“特殊”或“魔术”方法的命名规则是正确的。
虽然你可以直接调用这些方法(例如[10, 20].__len__()
),但下划线的存在暗示了这些方法是间接调用的( len([10, 20])
) 。 大多数python运算符都有一个关联的“magic”方法(例如, a[x]
是调用a.__getitem__(x)
的常用方法)。
双下划线包围的名字对Python来说是“特殊的”。 它们在“ Python语言参考”第3节“数据模型”中列出。
实际上,当我需要区分父类和子类名称时,我使用_方法名称。 我读过一些使用这种方式创build父子类的代码。 作为一个例子,我可以提供这个代码:
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) )
…