I have some object oriented code in Python, where some classes are meant to be extended to provide the missing custom bits of code (a la Template Method pattern, but also with variables), that will only be used by the super class, not by the client code using them.
Are there any style conventions for such abstract (or dull, because their implementation in the super class would be either pass
or raise a NonImplemented
exception) methods and attributes?
I've been browsing the PEP-0008 and it only mentions about prepending an underscore to private members not intended to be used by subclasses.
First of all i think that you are mistaken when you say that:
about prepending underscore to private members not intended to be used by subclasses.
Actually prepending a method/attribute by underscore is a python convention that mean that this method/attribute shouldn't be accessed outside the class (and its subclass) and I think you forgot to read about the double underscore that is used to make a method/attribute not possible to override.
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".
There is another way of declaring stub method by the way which is using abc.ABCMeta and abc.abstractmethod.
I usually use single underscore e.g. _myvar
for protected (as in C++) methods/attributes, which can be used by derived classes and use double underscore e.g. __var
when it should not be used by anybody else, and as double-underscore names at class definition level are mangled, so they can't be overridden in derived class e.g.
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()
Here it seems derived class B
is overriding both _calc1
and __calc2
but __calc2
isn't overridden because its name is already mangled with class name and hence output is
a1 a2
b1 a2
instead of
a1 a2
b1 b2
but ultimately choose any convention and document it, also in above case it is not that base class can't override private, here is a way :)
class B(A):
def _calc1(self):
return 'b1'
def _A__calc2(self):
return 'b2'
There isn't really a naming convention for these methods because they'll have the same name when they're overridden. Otherwise they wouldn't be overridden! I think having the method to be overridden do something trivial, and documenting it accordingly, is good enough:
class MyClass:
def aMethod():
'''Will be overridden in MyDerivedClass'''
pass
Name mangling, which you mention in your question, is useful if you have a non-trivial method that will be overridden, but you still want to be able to access the base version. See the documentation for more info and an example.
来源:https://stackoverflow.com/questions/7809287/python-naming-conventions-for-attributes-and-methods-meant-to-be-overwritten