Python属性和方法的命名约定(可重写)
3 个回答
2
其实这些方法没有特别的命名规则,因为当它们被重写的时候,名字是一样的。要不然就不能重写了!我觉得让被重写的方法做一些简单的事情,并且把这个说明清楚就可以了:
class MyClass:
def aMethod():
'''Will be overridden in MyDerivedClass'''
pass
你提到的名字改编(name mangling)是很有用的,特别是当你有一个比较复杂的方法需要被重写,但你还是想访问原来的版本。想了解更多信息和例子,可以查看这个文档。
13
我通常用一个下划线,比如 _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
不过最终你可以选择任何一种命名规则并记录下来。在上面的例子中,基类并不是不能覆盖私有属性,这里有一种方法可以做到 :)
class B(A):
def _calc1(self):
return 'b1'
def _A__calc2(self):
return 'b2'
10
首先,我觉得你在说这句话的时候有些误解:
关于在私有成员前加下划线,这些成员不打算被子类使用。
其实,在方法或属性前加下划线是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。