for*_*ran 7 python naming-conventions template-method-pattern
我在Python中有一些面向对象的代码,其中一些类要扩展以提供缺少的自定义代码位(模板方法模式,但也包含变量),只能由超类使用,而不是由使用它们的客户端代码.
对于这样的抽象是否有任何样式约定(或者是沉闷的,因为它们在超类中的实现会是pass或者引发NonImplemented异常)方法和属性?
我一直在浏览PEP-0008,它只提到将下划线添加到不打算由子类使用的私有成员.
Anu*_*yal 12
我通常使用单个下划线,例如_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()
Run Code Online (Sandbox Code Playgroud)
这里似乎派生类B重写了两个_calc1,__calc2但是__calc2没有被覆盖,因为它的名称已经被类名破坏了,因此输出是
a1 a2
b1 a2
Run Code Online (Sandbox Code Playgroud)
代替
a1 a2
b1 b2
Run Code Online (Sandbox Code Playgroud)
但最终选择任何约定并记录它,在上面的情况下它不是基类不能覆盖私有,这里是一种方式:)
class B(A):
def _calc1(self):
return 'b1'
def _A__calc2(self):
return 'b2'
Run Code Online (Sandbox Code Playgroud)
首先,我认为你错了,当你说:
关于将下划线预先添加到不打算由子类使用的私有成员.
实际上通过下划线预先设置方法/属性是一个python约定,意味着不应该在类(及其子类)之外访问此方法/属性,我想你忘了阅读用于创建方法的双下划线/ attribute无法覆盖.
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".
Run Code Online (Sandbox Code Playgroud)
还有另一种通过使用abc.ABCMeta和abc.abstractmethod来声明存根方法的方法.