要重写的属性和方法的Python命名约定



我在Python中有一些面向对象的代码,其中一些类被扩展以提供缺失的自定义代码位(一个模板方法模式,但也有变量),这些代码只会被超类使用,而不是被使用它们的客户端代码使用。

对于这些抽象方法和属性是否有任何样式约定(或沉闷,因为它们在超类中的实现将是pass或引发NonImplemented异常)?

我一直在浏览PEP-0008,它只提到在私有成员前加上下划线,而不打算由子类使用

我通常使用单下划线,例如_myvar保护(如在c++中)的方法/属性,这可以由派生类使用,并使用双下划线,例如__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

,但最终选择任何约定并记录它,同样在上面的情况下,并不是基类不能重写private,这里有一种方法:)

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

首先我认为你说错了:

关于在不打算被子类使用的私有成员前面加上下划线。

实际上,在方法/属性前加上下划线是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。ABCMeta和abc.abstractmethod.

这些方法没有真正的命名约定,因为当它们被覆盖时它们将具有相同的名称。否则它们不会被覆盖!我认为让被重写的方法做一些微不足道的事情,并相应地记录它,就足够了:

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

Name mangling,你在你的问题中提到的,是有用的,如果你有一个重要的方法,将被覆盖,但你仍然希望能够访问基本版本。更多信息和示例请参见文档

最新更新