Adding a method to an existing object instance
In Python, there is a difference between functions and bound methods.
>>> def foo():
... print "foo"
...
>>> class A:
... def bar( self ):
... print "bar"
...
>>> a = A()
>>> foo
<function foo at 0x00A98D70>
>>> a.bar
<bound method A.bar of <__main__.A instance at 0x00A9BC88>>
>>>
Bound methods have been "bound" (how descriptive) to an instance, and that instance will be passed as the first argument whenever the method is called.
Callables that are attributes of a class (as opposed to an instance) are still unbound, though, so you can modify the class definition whenever you want:
>>> def fooFighters( self ):
... print "fooFighters"
...
>>> A.fooFighters = fooFighters
>>> a2 = A()
>>> a2.fooFighters
<bound method A.fooFighters of <__main__.A instance at 0x00A9BEB8>>
>>> a2.fooFighters()
fooFighters
Previously defined instances are updated as well (as long as they haven't overridden the attribute themselves):
>>> a.fooFighters()
fooFighters
The problem comes when you want to attach a method to a single instance:
>>> def barFighters( self ):
... print "barFighters"
...
>>> a.barFighters = barFighters
>>> a.barFighters()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: barFighters() takes exactly 1 argument (0 given)
The function is not automatically bound when it's attached directly to an instance:
>>> a.barFighters
<function barFighters at 0x00A98EF0>
To bind it, we can use the MethodType function in the types module:
>>> import types
>>> a.barFighters = types.MethodType( barFighters, a )
>>> a.barFighters
<bound method ?.barFighters of <__main__.A instance at 0x00A9BC88>>
>>> a.barFighters()
barFighters
This time other instances of the class have not been affected:
>>> a2.barFighters()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'barFighters'
More information can be found by reading about descriptors and metaclass programming.
Any elegant way to add a method to an existing object in python?
Normally, functions stored in object dictionaries don't automatically turn into boundmethods when you look them up with dotted access.
That said, you can use functools.partial to pre-bind the function and store it in the object dictionary so it can be accessed like a method:
>>> from functools import partial
>>> class Dog:
def __init__(self, name):
self.name = name
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> def bark(self): # normal function
print('Woof! %s is barking' % self.name)
>>> e.bark = partial(bark, e) # pre-bound and stored in the instance
>>> e.bark() # access like a normal method
Woof! Buddy is barking
This is a somewhat elegant way to add a method to an existing object (without needing to change its class and without affecting other existing objects).
Follow-up to Comment:
You can use a helper function to add the pre-bound function is a single step:
>>> def add_method(obj, func):
'Bind a function and store it in an object'
setattr(obj, func.__name__, partial(func, obj))
Use it like this:
>>> add_method(e, bark)
>>> e.bark()
Woof! Fido is barking
Hope this is exactly what you need :-)
Adding a property to an existing object instance
This comment gave a hint to the answer.
The follow function (inspired on 1) adds a property to a single instance of a class. It does it by creating a new class on the fly.
def attach_dyn_propr(instance, prop_name, propr):
"""Attach property proper to instance with name prop_name.
Reference:
* https://stackoverflow.com/a/1355444/509706
* https://stackoverflow.com/questions/48448074
"""
class_name = instance.__class__.__name__ + 'Child'
child_class = type(class_name, (instance.__class__,), {prop_name: propr})
instance.__class__ = child_class
Example and test:
def getter(self): print('Get!')
def setter(self, value): print('Set to {!r}!'.format(value))
def deleter(self): print('Delete!')
prop = property(getter, fset=setter, fdel=deleter)
class Foo: pass
foo = Foo()
foo2 = Foo()
attach_dyn_propr(foo, 'p', prop)
foo.p
foo2.p
... Get
... AttributeError: 'Foo' object has no attribute 'p'
How can I add method to an existing object in Java?
If loadShape()
returns a PShape
, then it returns a PShape
. You can't make it return a subclass of PShape
.
Easiest approach would be Shape
either copies the PShape
into a new instance:
e.g.
Shape myLoadShape(String filename)
{
return new Shape(loadShape(filename));
// Assumes you have a `Shape(PShape)` constructor.
}
or perhaps Shape
isn't a subclass, but it contains a PShape
data member.
class Shape
{
// No one picked up my C++ syntax goof ;-)
protected PShape pshape;
// Using a constructor is just one way to do it.
// A factory pattern may work or even just empty constructor and a
// load() method.
public Shape(String filename)
{
pshape = loadShape(filename);
// Add any Shape specific setup
}
}
How to add method to existing class in Python?
Use python class inheritance. This will allow you to use all the methods in a Pandas data frame and still define your own methods.
import pandas as pd
class NewDF(pd.DataFrame)
def __init__(self, *args):
pd.DataFrame.__init__(self, *args)
def to_file(df, path, sep="\t", compression="infer", pickled="infer", verbose=False, **args):
...
Adding `__getattr__` method to an existing object instance
You can not - __dunder__
names are resolved on the type, not per-instance. Custom __getattr__
will need to be defined directly on A
.
See Special method lookup section of the datamodel documentation, specifically:
For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.
Note: if you only have a reference to an instance, not the class, it is still possible to monkeypatch the type by assigning a method onto the object returned by type(a)
. Be warned that this will affect all existing instances, not just the a
instance.
Related Topics
How to Execute a Program or Call a System Command
What Does the "Yield" Keyword Do
How to Make Python Script Run as Service
How to Use "/" (Directory Separator) in Both Linux and Windows in Python
How to Detect Collision in Pygame
"Is" Operator Behaves Unexpectedly With Integers
Hex/Binary String Conversion in Swift
Os.Walk Without Hidden Folders
Python Script as Linux Service/Daemon
Call to Operating System to Open Url
How to Split a List into Equally-Sized Chunks
Selenium - Wait Until Element Is Present, Visible and Interactable
How to Use Export With Python on Linux
Get a List of Numbers as Input from the User