【问题标题】:In Python 2 do we need a self keyword for a function even if the function isn't part of a class?在 Python 2 中,我们是否需要一个函数的 self 关键字,即使该函数不是类的一部分?
【发布时间】:2022-01-23 07:11:32
【问题描述】:

所以我正在查看一些旧的 python 2 代码,我看到了这个函数

def manage_addMapSamlPlugin(self, id, title='', delegate_path='', REQUEST=None):
  """ Factory method to instantiate a MapSamlPlugin """
  # Make sure we really are working in our container (the
  # PluggableAuthService object)
  self = self.this()                         
  # Instantiate the adapter object
  lmp = MapSamlPlugin(id, title=title, delegate_path=delegate_path )
  self._setObject(id, lmp)
  if REQUEST is not None:
    REQUEST.RESPONSE.redirect('%s/manage_main' % self.absolute_url())

现在这个函数在一个类之外,代码编译并且没有给出任何错误。我的理解是,在这种情况下, self 关键字只是传入的任何内容,但是 self.this() 和 self._setObject(id, lmp) 不应该是正确的?编译器不应该抛出错误吗?该代码在 ssh 服务器的终端上运行,我不知道它使用什么编译器。 在文件的末尾,这是函数被调用的地方。

def initialize(context):
  registerMultiPlugin(MapSamlPlugin.meta_type)
  context.registerClass(
    MapSamlPlugin,
    constructors=(manage_addMapSamlPluginForm, manage_addMapSamlPlugin),
    permission=ManageUsers,
    icon=os.path.join(mgr_dir, "saml_icon.png"),
    visibility=None,
    )

这也是一个独立的函数“上下文”不是从任何导入或类派生的。

【问题讨论】:

  • 为什么会报错? self 不是关键字,甚至不是内置名称。这只是一个约定。但它没有任何特殊意义。您还可以在类中将self 替换为baz...
  • self 不是关键字。 self传统上赋予方法的第一个位置参数的名称,当在实例上调用方法时将隐式传递给实例。

标签: python python-2.x


【解决方案1】:

评论是一条重要线索:

def manage_addMapSamlPlugin(self, id, title='', delegate_path='', REQUEST=None):
  """ Factory method to instantiate a MapSamlPlugin """
  # Make sure we really are working in our container (the
  # PluggableAuthService object)
  self = self.this()     

self 应该是一个具有this() 方法的对象——听起来该方法返回一个PluggableAuthService 对象。如果您用 grep 查找 def this 的其余代码,您可能会找到它。寻找class PluggableAuthService 也可能会有所启发。

如果您调用此函数并将未实现预期接口的self 传递给它,您将在运行时获得AttributeError。由于这里没有类型注释,因此实际上没有办法静态捕获错误(在“编译时”——尽管通常编译 Python 本身并不强制执行任何静态类型检查)。

我怀疑这个函数最初是那个类的一个方法,并且由于某种原因被重构出来(也许是一些从未完成的更大重构的第一步)。如果您将一个类方法从一个类中拉出,它就可以正常工作,前提是您在调用它时显式提供self 参数。

【讨论】:

  • 搜索文件的唯一 PluggableAuthService 来自导入。 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin from Products.PluggableAuthService import registerMultiPlugin 这是否意味着我需要为 PluggableAuthService 创建一个类,或者它只是工作并从导入中找到它需要的东西?
  • 我需要为 PluggableAuthService 创建一个类——为了做什么?看起来这个函数被 registerClass 函数调用了。您可能应该先弄清楚它是如何工作的,然后再尝试自己调用这个特定的函数。更好的是,如果您不必出于任何特定原因修改此代码,只需远离它,再也不要考虑它。 :P
  • 如果您确实需要尝试维护此代码,我的第一步是对整个内容进行类型注释(使用 mypy 在 Python 2 中支持的注释语法)。没有注释就完全无法理解,因为参数需要具有特定的类型,但没有任何明确的指示说明这些类型是什么。
  • 我无法使用 mypy 我的版本是 Python 2.4,还有其他我可以使用的库吗?试过 pip install 'mypy[python2]'
  • 安装 Python3 并使用它在 Python2 代码上运行 mypy。 mypy.readthedocs.io/en/stable/…如果你想维护这段代码,你最终应该把它迁移到Python3; mypy 对此也很有帮助,因为类型注释将帮助您在迁移时不会破坏事情。
猜你喜欢
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多