有没有办法在Python中覆盖实例级别的类方法?例如:
class Dog:
def bark(self):
print "WOOF"
boby = Dog()
boby.bark() # WOOF
# METHOD OVERRIDE
boby.bark() # WoOoOoF!!
Run Code Online (Sandbox Code Playgroud) 有没有办法在len()不修改类的情况下使用实例方法?
我的问题的例子:
>>> class A(object):
... pass
...
>>> a = A()
>>> a.__len__ = lambda: 2
>>> a.__len__()
2
>>> len(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'A' has no len()
Run Code Online (Sandbox Code Playgroud)
注意:
A将__len__附加不同的方法A我希望能够通过单击QTreeView中没有项目的部分来取消选择QTreeView中的项目,但我似乎无法找到这样做.我拦截了一个不在项目上的点击,但是QTreeView没有clicked信号,所以我无法弄清楚如何做到这一点.
问:有没有办法在Python(3.6)中改变现有对象的方法?("方法"是指self作为参数传递的函数.)
例
假设我有一个类Person有一些非常有用的方法SayHi():
class Person(object):
Cash = 100
def HasGoodMood(self):
return self.Cash > 10
def SayHi(self):
if self.HasGoodMood():
print('Hello!')
else:
print('Hmpf.')
>>> joe = Person()
>>> joe.SayHi()
Hello!
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,人的反应取决于他们通过该方法计算的当前情绪HasGoodMood().默认情况下,只要他们有10美元以上的现金,他们就会心情愉快.
我可以很容易地创造一个不关心金钱并且一直很开心的人:
>>> joe.HasGoodMood = lambda: True
>>> joe.SayHi()
Hello!
>>> joe.Cash = 0
>>> joe.SayHi()
Hello!
Run Code Online (Sandbox Code Playgroud)
凉.请注意Python如何知道在使用原始实现时HasGoodMood,它会以静默方式self作为第一个参数传递,但如果我将其更改为lambda: True,则会调用不带参数的函数.问题是:如果我想更改HasGoodMood另一个也接受self作为参数的函数的默认值,该怎么办?
让我们继续我们的例子:如果我想创造一个Person只有超过100美元的贪婪的人呢?我想做的事情如下:
>>> greedy_jack = Person()
>>> greedy_jack.HasGoodMood = lambda self: self.Cash > …Run Code Online (Sandbox Code Playgroud) 我想知道是否有一种可接受的方法将函数作为参数传递给对象(即在init块中定义该对象的方法)。
更具体地说,如果函数依赖于对象参数,我们将如何做到这一点。
将函数传递给对象似乎足够Pythonic,函数就像其他东西一样是对象:
def foo(a,b):
return a*b
class FooBar(object):
def __init__(self, func):
self.func = func
foobar = FooBar(foo)
foobar.func(5,6)
# 30
Run Code Online (Sandbox Code Playgroud)
这样就可以了,一旦引入对对象其他属性的依赖,问题就会出现。
def foo1(self, b):
return self.a*b
class FooBar1(object):
def __init__(self, func, a):
self.a=a
self.func=func
# Now, if you try the following:
foobar1 = FooBar1(foo1,4)
foobar1.func(3)
# You'll get the following error:
# TypeError: foo0() missing 1 required positional argument: 'b'
Run Code Online (Sandbox Code Playgroud)
这可能简单地违反了 python 中 OOP 的一些神圣原则,在这种情况下,我只需要做其他事情,但它似乎也可能被证明是有用的。
我想出了几种可能的方法来解决这个问题,我想知道哪种(如果有的话)被认为是最可接受的。
foobar1.func(foobar1,3)
# 12
# seems ugly
Run Code Online (Sandbox Code Playgroud)
class FooBar2(object):
def __init__(self, …Run Code Online (Sandbox Code Playgroud)