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