2016-03-14 69 views
1

我想向類中添加一個函數,它應該適用於該類中的所有對象,如果它們是之前創建的。但我不知道已經創建的對象的名稱。Python 3:將函數添加到已創建的對象

class Dog(object): 
"""This is a simple test""" 
i = 1234 
def f(self): 
    return 'hello world' 

如果我想要實現的功能bark到類Dog和已經創建的狗可以「利用」這個功能,我會怎麼做呢?

我在網上搜索之前,發現

a = Dog() 
a.bark = types.MethodType(...) 

但我不能使用,因爲我不知道該對象的名稱。也許不知何故,你可以從一個類中找出對象的名字。

你能幫我嗎?

謝謝! NoAbL

+1

做'Dog.bark = ...',而不是'a.bark = ...' – inspectorG4dget

+0

@ inspectorG4dget :你應該發佈這個答案。 – tjohnson

+0

噢...我很抱歉問這個問題:D我可以猜出解決方案... – NoAbL

回答

3

你是對的,a.bark修改Dog的特定實例,而不是類本身。

如果你想修改Dog類,那麼你應該找到討論該類的變量。幸運的是,該變量可以方便地以該類名稱命名(與python中的任何類一樣),因此可以使用變量名稱Dog來訪問該變量。

所以,如果你做

Dog.bark = types.MethodType(...) 

是會改變的狗類,使得bark可用的Dog(無論你做出這種改變之前,他們是否存在)的所有實例

1

要改變只有實例方法(不是Dog類,你可以這樣做)

import functools 
dog.bark = functools.partial(f, dog) 
1

Python對象並不是真的那樣工作。函數實際上與實例(或綁定)方法不同。有一對夫婦的事情,你可以做,但我不一定會推薦例如:

import types # needed for assigning it to a method type 

class foo: 
    def __init__(self, i): 
     self.i = i 

a = foo(7) 
b = foo(3) 

def bar(self): 
    return self.i 

vars = dict(globals()) 
vars.update(locals()) 

for var in vars: 
    if isinstance(vars[var], foo): 
     vars[var].bar = types.MethodType(bar, vars[var]) 

print(a.bar()) # => 7 
print(b.bar()) # => 3 

然而,這顯然是一個創可貼,並沒有解決真正的問題。一旦你創建了一個類的實例,它只能改變這麼多。 INSTANCE可以改變,但它不會一次影響所有實例,除非您覆蓋某些數據。例如,我可以做foo.i = 100,然後a.ib.i都是100.但是,這似乎並不是你想要的。

東西勝負的接近可能的,但可以更好地突出這個問題:

class foo: 
    def __init__(self, i): 
     self.i = i 

a = foo(7) 
b = foo(3) 

def bar(self): 
    return self.i 

foo.bar = types.MethodType(bar, a) 
print(a.bar()) # => 7 
print(b.bar()) # => 7 
foo.bar = types.MethodType(bar, b) 
print(a.bar()) # => 3 
print(b.bar()) # => 3 
foo.bar = types.MethodType(bar, foo) 
print(a.bar()) # => AttributeError: class foo has no attribute 'i' 
相關問題