如何避免在python中意外重写方法?
我知道有很多类似的问题。但我的问题不同。 我不想创建一个无法重写的方法。 我想保护我新创建的类,以免意外重写某些内容 使用下划线作为前缀是很好的,但是很快我就会得到很多带有很多下划线的方法。在我继承的类中的某个地方,我将重写grand祖先的类方法 我真正想要的是这么简单的东西:如何避免在python中意外重写方法?,python,class,Python,Class,我知道有很多类似的问题。但我的问题不同。 我不想创建一个无法重写的方法。 我想保护我新创建的类,以免意外重写某些内容 使用下划线作为前缀是很好的,但是很快我就会得到很多带有很多下划线的方法。在我继承的类中的某个地方,我将重写grand祖先的类方法 我真正想要的是这么简单的东西: class Cat(Mammal): def walk(self): if ancestor_has_function('walk'): parent.walk();
class Cat(Mammal):
def walk(self):
if ancestor_has_function('walk'):
parent.walk();
do_something_here();
如果猫的任何祖先(无论是哺乳动物、动物还是生命体)有“walk”方法,那么应该首先执行父方法
这是否有可能在python中实现
编辑:
例如,这是我认为不错的答案的简历。希望这将有助于其他人:
class Animal(object):
pass
#def walk(self):
# print('animal walk')
class Mammal(Animal):
def walk(self):
if hasattr(super(Mammal, self), 'walk') and callable(super(Mammal,self).walk):
super(Mammal, self).walk()
print('mammal walk')
class Cat(Mammal):
def walk(self):
super(Cat, self).walk()
print('cat walk')
if __name__ == '__main__':
cat = Cat()
cat.walk()
以下是输出:
哺乳动物行走
猫步
尝试取消对Animal的walk方法的注释,您也可以让它工作。您可以将原始方法保留在字段中
class MyClass:
def __method(self):
pass
def __init__(self):
self.method = __method
然后检查标识并调用保存的方法您可以将原始方法保留在字段中
class MyClass:
def __method(self):
pass
def __init__(self):
self.method = __method
然后检查标识并调用保存的方法您可以使用dir()
函数获取为某个模块或类声明的所有名称。层次结构中更高级别的类中声明的方法也将包括在内。但是,请注意,这也将包括属性,因此请首先检查callable()
另外,调用父方法在python中看起来有点不同,请参见下面的代码
def walk(self):
if "walk" in dir(Mammal) and callable(Mammal.walk):
Mammal.walk(self)
# do something
您可以使用dir()
函数获取为某个模块或类声明的所有名称。层次结构中更高级别的类中声明的方法也将包括在内。但是,请注意,这也将包括属性,因此请首先检查callable()
另外,调用父方法在python中看起来有点不同,请参见下面的代码
def walk(self):
if "walk" in dir(Mammal) and callable(Mammal.walk):
Mammal.walk(self)
# do something
是的
hasattr
检查是否存在具有特定名称的属性。
和callable
检查特定属性是否可调用
class Mammal(object):
def walk(self):
print "walking"
class Cat(Mammal):
def walk(self):
if hasattr(Mammal,'walk') and callable(Mammal.walk):
Mammal.walk(self);
print "another walking!"
现在:
>>> my_cat = Cat()
>>> my_cat.walk()
walking
another walking!
请注意,您还可以使用super
获得这样的父类:
if hasattr(super(Cat, self),'walk'):
是的
hasattr
检查是否存在具有特定名称的属性。
和callable
检查特定属性是否可调用
class Mammal(object):
def walk(self):
print "walking"
class Cat(Mammal):
def walk(self):
if hasattr(Mammal,'walk') and callable(Mammal.walk):
Mammal.walk(self);
print "another walking!"
现在:
>>> my_cat = Cat()
>>> my_cat.walk()
walking
another walking!
请注意,您还可以使用super
获得这样的父类:
if hasattr(super(Cat, self),'walk'):
一般来说,您可能希望在最通用的超类中至少提供一个存根方法:
class Mammal(object):
def walk(self):
pass
然后,通过调用super()
,在子类中扩展它:
使super()
调用有条件并不困难,但这可能是一个坏主意:它冗长、脆弱,只会鼓励不良做法。如果您确实有很好的理由这样做,您可以像处理任何其他对象一样,在super
对象上使用hasattr()
:
class Cat(Mammal):
def walk(self):
if hasattr(super(Cat, self), 'walk'):
super(Cat, self).walk()
do_something_here()
不过,您可能只希望在不寻常的情况下执行此操作,例如,出于某种原因,您无法依赖于存在的某些方法的第三方库中的类的子类化。一般来说,您可能希望在最通用的超类中至少提供一个存根方法:
class Mammal(object):
def walk(self):
pass
import inspect
class SomeClass():
def __init__(self):
...
def somefunc(self):
....
def someOtherFunc(self):
....
allmembers = inspect.getmembers(SomeClass, predicate=inspect.ismethod)
然后,通过调用super()
,在子类中扩展它:
使super()
调用有条件并不困难,但这可能是一个坏主意:它冗长、脆弱,只会鼓励不良做法。如果您确实有很好的理由这样做,您可以像处理任何其他对象一样,在super
对象上使用hasattr()
:
class Cat(Mammal):
def walk(self):
if hasattr(super(Cat, self), 'walk'):
super(Cat, self).walk()
do_something_here()
不过,您可能只希望在不寻常的情况下执行此操作,例如,由于某种原因,您无法依赖于存在某些方法的第三方库中的类的子类化
import inspect
class SomeClass():
def __init__(self):
...
def somefunc(self):
....
def someOtherFunc(self):
....
allmembers = inspect.getmembers(SomeClass, predicate=inspect.ismethod)
getmembers
返回给定类中定义的所有方法的列表,它是包含方法名称和定义的元组列表:
[('__init__', <unbound method SomeClass.__init__>),
('somefunc', <unbound method SomeClass.somefunc>),
('someOtherFunc', <unbound method SomeClass.someOtherFunc>)]
您可以获取类中定义的所有方法的列表,并检查是否有类似名称的方法,因为getmembers
返回未绑定的方法实例,您也可以轻松访问该函数
getmembers
返回给定类中定义的所有方法的列表,它是包含方法名称和定义的元组列表:
[('__init__', <unbound method SomeClass.__init__>),
('somefunc', <unbound method SomeClass.somefunc>),
('someOtherFunc', <unbound method SomeClass.someOtherFunc>)]
您可以获取类中定义的所有方法的列表,并检查是否有类似名称的方法,因为
getmembers
返回未绑定的方法实例,您也可以轻松访问该函数。@Piet拥有它。不要有条件地重写方法——始终重写它们,并使用super()
@katrielex调用原始方法Animal
类可以有或没有walk
方法。假设它是第三方库,您无法确保它是否有特定的方法,您将看到为什么有必要使用条件语句。@Piet有它。不要有条件地重写方法——始终重写它们,并使用super()
@katrielex调用原始方法Animal
类可以有或没有walk
方法。假设它是第三方库,您无法确保它是否有特定的方法,您将看到为什么有必要使用条件语句
。我以前从未知道python有“super”方法。它也适用于python 2.7吗?是的:super()
是与python 2.2中的新样式类一起引入的。我以前从未知道python有“super”方法。它是否也适用于Python2.7?是的:super()
与Python2.2中的新样式类一起引入。