Reputation: 95
I want to add a function to a class, and it should work for all objects from that class, also if they were created before. BUT I don't know the names of the objects already created.
class Dog(object):
"""This is a simple test"""
i = 1234
def f(self):
return 'hello world'
If i want to implement a function bark
to the class Dog
and already created Dogs can "use" this function, how would i do this?
I was searching in the Internet before and found
a = Dog()
a.bark = types.MethodType(...)
But i can't use that, because i don't know the name of the object. Maybe somehow you can find out the names of objects from a class.
Can you help me?
Thanks! NoAbL
Upvotes: 1
Views: 282
Reputation: 4681
Python objects don't really work like that. Functions are actually different from instance (or bound) methods. There are a couple things that you COULD do, but I wouldn't necessarily recommend For example:
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
This, however, is obviously a band-aid and doesn't address the real problem. Once you create an instance of a class, it can change only so much. The INSTANCE can change, but it won't affect all instances at once unless you overwrite certain data. For example, I could do foo.i = 100
and then both a.i
and b.i
would be 100. This doesn't seem to be what you want, however.
Something kinda-sorta close may, but may better highlight the issues of this:
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'
Upvotes: 1
Reputation: 8066
To change only the instance method (not the Dog class you can do it like this)
import functools
dog.bark = functools.partial(f, dog)
Upvotes: 1
Reputation: 113915
You're right that a.bark
modifies the specific instance of Dog
and not the class itself.
If you want to modify the Dog class, then you should find the variable that talks about the class. Luckily, that variable is conveniently named after the name of the class itself (as is the case with any class in python), and can therefore be accessed with the variable name Dog
.
So, if you do
Dog.bark = types.MethodType(...)
that'll change the Dog class, making bark
available to all instances of Dog
(regardless of whether they existed before you made this change)
Upvotes: 3