这种“下划线”似乎经常出现,我想知道这是Python语言的要求,还是仅仅是一种惯例?
另外,有没有人可以命名并解释哪些函数倾向于有下划线,以及为什么(例如__init__)?
这种“下划线”似乎经常出现,我想知道这是Python语言的要求,还是仅仅是一种惯例?
另外,有没有人可以命名并解释哪些函数倾向于有下划线,以及为什么(例如__init__)?
当前回答
来自Python PEP 8——Python代码风格指南:
Descriptive: Naming Styles The following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention): _single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore. single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g. Tkinter.Toplevel(master, class_='ClassName') __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below). __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
请注意,带有双前导和双尾下划线的名称本质上是为Python本身保留的:“永远不要发明这样的名称;只在文档中使用它们”。
其他回答
其他受访者正确地将双开头和结尾下划线描述为“特殊”或“神奇”方法的命名约定。
虽然您可以直接调用这些方法(例如[10,20].__len__()),但下划线的存在暗示这些方法将被间接调用(例如len([10,20]))。大多数python操作符都有一个相关的“magic”方法(例如,a[x]是调用a.__getitem__(x)的通常方式)。
来自Python PEP 8——Python代码风格指南:
Descriptive: Naming Styles The following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention): _single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore. single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g. Tkinter.Toplevel(master, class_='ClassName') __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below). __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
请注意,带有双前导和双尾下划线的名称本质上是为Python本身保留的:“永远不要发明这样的名称;只在文档中使用它们”。
实际上,当我需要区分父类名和子类名时,我使用_方法名。我读过一些使用这种方式创建父-子类的代码。作为一个例子,我可以提供以下代码:
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来说是“特殊的”。它们在Python语言参考第3节“数据模型”中列出。
此约定用于特殊变量或方法(所谓的“魔术方法”),如__init__和__len__。这些方法提供特殊的语法特性或做特殊的事情。
例如,__file__表示Python文件的位置,当a == b表达式执行时执行__eq__。
用户当然可以创建一个自定义的特殊方法,这是非常罕见的情况,但通常可能会修改一些内置的特殊方法(例如,你应该用__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