2016-03-14 2 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

Do '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.i, и b.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' 
Смежные вопросы