首页 文章

为什么有些函数在函数名之前和之后都加上了“__”?

提问于
浏览
349

这似乎发生了很多,并且想知道这是否是Python语言中的要求,还是仅仅是常规问题?

此外,有人可以命名并解释哪些功能往往具有下划线,以及为什么(例如 __init__ )?

4 回答

  • 48

    来自Python PEP 8 -- Style Guide for Python Code

    描述性:命名样式使用前导或尾部下划线的以下特殊形式被识别(这些通常可以与任何案例约定结合):_ single_leading_underscore:弱“内部使用”指示符 . 例如 . 来自M import *不会导入名称以下划线开头的对象 . single_trailing_underscore_:由约定用于避免与Python关键字冲突,例如Tkinter.Toplevel(master,class _ ='ClassName')__ load_leading_underscore:在命名一个class属性时,调用name mangling(在类FooBar中,__ boo变成_FooBar__boo;见下文) . double_leading_and_trailing_underscore:生成在用户控制的命名空间中的“魔术”对象或属性 . 例如 . init import__或__file . 不要发明这样的名字;仅按记录使用它们 .

    请注意,具有双前导和尾部下划线的名称基本上是为Python本身保留的:“永远不要创建这样的名称;只能按照文档使用它们” .

  • 447

    其他受访者将双引导和尾随下划线描述为“特殊”或“魔术”方法的命名约定是正确的 .

    虽然您可以直接调用这些方法(例如 [10, 20].__len__() ),但下划线的存在暗示这些方法是间接调用的(例如 len([10, 20]) ) . 大多数python运算符都有一个关联的"magic"方法(例如, a[x] 是调用 a.__getitem__(x) 的常用方法) .

  • 5

    双下划线包围的名称是Python的"special" . 它们列在Python Language Reference, section 3, "Data model"中 .

  • 14

    实际上,当我需要在父类和子类名称之间有所不同时,我使用_方法名称 . 我已经阅读了一些使用这种创建父子类的代码 . 作为示例,我可以提供此代码:

    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)
        )
    

    ...

相关问题