【问题标题】:Why can't I call a private method when I'm inside a public method?为什么当我在公共方法中时不能调用私有方法?
【发布时间】:2011-06-21 12:49:34
【问题描述】:

我有以下代码:

class MyClass:
    def __private(self):
        print "Hey man! This is private!"

    def public(self):
        __private()
        print "I don't care if you see this!"

if __name__ == '__main__':
    x = MyClass()
    x.public()

但是它给了我以下错误:

NameError: global name '_MyClass__private' is not defined

我做错了什么?

【问题讨论】:

  • 另外,如果您还没有,请阅读文档的这一部分:docs.python.org/tutorial/classes.html#private-variables 单下划线是“私有”变量的典型约定。当你想避免继承自 MyClass 的类中的名称冲突时,通常只使用双下划线。双下划线将调用名称修饰,这可能是您想要的,但我想确保您知道它...
  • 请不要使用__。它保留用于“名称修饰”,这是 Python 在内部执行的一项操作,以确保内部名称永远不会发生冲突。

标签: python private public


【解决方案1】:

你需要self:

self.__private()

如果您来自 C#/C++/Java,python 中的类需要习惯,就像看起来一样。这可能是在扼杀“pythonic”的措辞方式,但你可以这样想(它帮助了我):

每个类都定义了一个命名空间,其内部定义为self,外部定义为该类实例的名称。带有两个下划线的“私人”事物会被破坏,因此您必须在外部使用特殊名称来调用它,但在内部您可以简单地使用 self.__private()

正如 Joe 在他的评论中提到的,普通私有变量通常只用一个下划线命名,双下划线会破坏它,因此继承可以在子类中没有名称冲突的情况下工作。在 python 中没有强制执行隐私,纯粹是约定说你不能在类外使用私有变量。

正如 Thomas 提到的,self 也是一个约定。对于任何方法(声明为类的一部分的函数),调用该方法的实例是传入的第一个参数。您可以很容易地这样做:

def __private(randomText):
    print "Hey man! This is private!"

def public(otherRandomText):
    otherRandomText.__private()
    print "I don't care if you see this!"

但是,如果您这样做,逻辑精神和良好的编程风格将永远困扰您和您的后代。 (self 更可取)。

任何pythonistas希望纠正/进一步解释?

【讨论】:

  • 别担心,伙计!我不能告诉你我这样做了多少次。每当您在语言之间切换时,它可能会一直发生。
  • @Bob @Cpfohl 是的,每次使用 PHP 时我也很兴奋,因为我花了这么多年的时间做 C++...
  • 精彩的解释。你假设我来自 C 风格语言 (C#) 是对的。
  • @Bob:我作弊并查看了你的标签... ;-)
  • 严格来说,self 这个名字是一个约定,不是硬编码的。类的任何方法都会自动将实例作为第一个变量传递,我们使用 self 来引用它。不过,这是学术性的:我从未见过有理由称它为 self 以外的任何东西。
【解决方案2】:

您的代码正试图调用静态函数 MyCalls.__private,您想要这样做:

class MyClass:
    def __private(self):
        print "Hey man! This is private!"

    def public(self):
        self.__private()
        print "I don't care if you see this!"

if __name__ == '__main__':
    x = MyClass()
    x.public()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 2011-09-19
    • 2010-09-24
    • 2023-03-08
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多