【问题标题】:Calling a private class member function in python from another module从另一个模块调用python中的私有类成员函数
【发布时间】:2017-04-12 16:05:06
【问题描述】:

是否可以调用 another 类中声明的私有函数?如果是,我需要在我的主文件中调用一个函数。此函数必须从另一个模块导入。该函数在一个类中定义如下。

class ConfLoader(object):
.....
    def _set_config_value(self, section, attribute, value):
....

有什么建议吗?

【问题讨论】:

  • Python中没有私有函数或方法,你用的是什么框架吗?
  • 您的函数以一个下划线开头。可以正常调用。
  • 虽然 Python 中确实没有真正的私有方法,但这里的下划线表示您不应该自己调用此函数。为什么你认为你需要?
  • 是的。 Python 中并没有真正的私有方法,只是约定某些事物应该被视为私有的。您可以像从另一个模块调用任何其他方法一样执行此操作,但请注意,编写该其他模块的人希望您不要使用该功能,因此它的行为可能与您期望的不同。
  • 你仍然需要实例化类并调用实例上的方法。

标签: python class import


【解决方案1】:

Python 没有“强制”的私有函数,但它确实有一个命名约定,这使得 意外 更难做到。这通常是通过添加一个 double 下划线来完成的(而不是像你的例子中那样,一个单一的,它作为一个普通的方法名称)。例如:

class X(object):
    def __f(self):
        print('hello')

如果我尝试在类定义之外使用相同的名称,它将失败:

>>> x = X()
>>> x.__f()
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    x.__f()
AttributeError: 'X' object has no attribute '__f'

相反,Python 使用_ClassName__PrivateMethod。我可以仍然使用以下方法在类定义之外调用这个伪私有函数:

>>> x._X__f()
hello

有关更多有用信息,请参阅Why are Python's 'private' methods not actually private?

当然,请注意,仅仅因为某事可能并不意味着它是一个好主意。设计良好的类具有私有函数是有原因的:这些是​​内部函数,不能与外部函数安全地交互。

【讨论】:

    【解决方案2】:

    Python 通过修改以两个下划线开头但不以下划线结尾的方法名称来实现伪私有方法。它只是将类名添加到前面。

    >>> class Foo(object):
    ...     def __private(self):
    ...         print('secret')
    ... 
    >>> dir(Foo)
    ['_Foo__private', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
    

    注意_Foo__private 方法名称。你可以叫那个名字。

    >>> Foo()._Foo__private()
    secret
    

    继承让事情变得很奇怪。请注意下面的子类有两个私有方法。子类需要意识到这一点,不要感到惊讶。如果您使用私有方法,您可能会发现您搞砸了从该类继承但仍想使用您的代码的任何人。

    >>> class Bar(Foo):
    ...     def __private(self):
    ...         print('secret 2')
    ... 
    >>> dir(Bar)
    ['_Bar__private', '_Foo__private', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
    

    私有方法不是实现者的公共接口的一部分,并且可以随时更改而不会违反公共接口。您可以使用它们,但请注意所有黑客规则都适用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多