我在python中有一些面向对象的代码,其中一些类是要扩展的,以提供缺少的代码自定义位(a la) 模板方法模式, ,但也有变量),这只能由超级类使用,而不是使用它们的客户端代码。

有什么样的风格约定 抽象的 (或乏味,因为他们在超级阶级中的实施将是 pass 或提出一个 NonImplemented 例外)方法和属性?

我一直在浏览 PEP-0008 而且它只提到准备强调 私人的 成员不打算由子类使用。

有帮助吗?

解决方案

首先,我认为当您这样说时,您会误解:

关于向不打算由子类使用的私人成员的准备。

实际上,通过下划线准备方法/属性是一个Python的约定,这意味着该方法/属性不应在类(及其子类)之外访问(及其子类),而且我认为您忘了阅读有关用来制作方法的双重下划线的阅读/属性不可能覆盖。

class Foo(object):
    def __foo(self):
        print "foo"
    def main(self):
        self.__foo()


class Bar(Foo):
    def __foo(self):
        print "bar"


bar = Bar()
bar.main()
# This will print "foo" and not "bar".

还有另一种方式来宣布存根方法的方式 ABC.AbcmetaABC.AbstractMethod.

其他提示

我通常使用单个下划线 _myvar 对于受保护的方法/属性,可以通过派生类使用并使用双重下划线 __var 当其他人不应该使用它时 陷入困境, ,因此在派生的班级中不能被覆盖

class A(object):
    def result1(self): # public method
        return self._calc1()

    def result2(self): # public method
        return self.__calc2()

    def _calc1(self): # protected method, can be overridden in derived class
        return 'a1'

    def __calc2(self): # private can't be overridden
        return 'a2'


class B(A):
    def _calc1(self):
        return 'b1'

    def __calc2(self):
        return 'b2'

a = A()
print a.result1(),a.result2()
b = B()
print b.result1(),b.result2()

这里似乎是派生的班级 B 两者都覆盖 _calc1__calc2__calc2 没有被覆盖,因为它的名称已经与班级名称混在一起,因此输出是

a1 a2
b1 a2

代替

a1 a2
b1 b2

但是最终选择任何惯例并记录下来,在上面的情况下也不是基本类不能覆盖私人,这是一种方法:)

class B(A):
    def _calc1(self):
        return 'b1'

    def _A__calc2(self):
        return 'b2'

这些方法实际上没有一个命名的惯例,因为当它们被覆盖时,它们的名称会相同。否则他们不会被覆盖!我认为拥有被覆盖的方法做一些微不足道的事情,并相应地记录了它,就足够好:

class MyClass:

  def aMethod():
    '''Will be overridden in MyDerivedClass'''
    pass

您在问题中提到的名称Mangling如果您有一种非平凡的方法被覆盖,但您仍然希望能够访问基本版本,这将很有用。看 文档 有关更多信息和示例。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top