Reputation: 77
I want to forward all of the unknown functions in my own class definition to an object in that class. One could directly access the object in the class, but was wondering if there is a pythonic way to pass all of the methods that belong to this object directly. Look at it as a 'catch-all' for methods or passthrough.
Tried getattr but failed to get it to do exactly what I want it to do.
class MyClass():
def __init__(self, name, object):
self.name = name
self.object = object
def known_function(self):
return '{}_blabla'.format(self.name)
def all_unknown_functions(self):
return self.object.thisunknownfunction()
Want: all of the unknown functions to pass through to the object inside my class, without me having to re-define all of these functions.
edit: the getattr method would be the same as the all_unknown_functions method edit2: fixed the parameter in known_function
Upvotes: 3
Views: 2047
Reputation: 42107
You can override __getattr__
and add your self.object
search logic for missing attribute there:
class MyClass():
def __init__(self, name, obj):
self.name = name
self.obj = obj
def known_function(self, name):
return '{}_blabla'.format(name)
def __getattr__(self, attr):
if attr not in self.__dict__:
return getattr(self.obj, attr)
return super().__getattr__(attr)
m = MyClass('foo', str)
m.lower
# <method 'lower' of 'str' objects>
m.known_function('spam')
# 'spam_blabla'
Here we're checking if the attr
is in the instance dict, if not we get the attribute from self.obj
.
Note that, this will get any attribute, not only a function. You can add a types.MethodType
check later.
Also, you've referred the name name
in known_function
, which does not exist in the local scope, you presumably meant to take a name
argument or
use self.name
.
Edit:
Actually __getattr__
is called last in the attribute lookup chain, so you can drop the check for self.__dict__
as this check has been done earlier already, so do:
class MyClass():
def __init__(self, name, obj):
self.name = name
self.obj = obj
def known_function(self, name):
return '{}_blabla'.format(name)
def __getattr__(self, attr):
return getattr(self.obj, attr)
Upvotes: 6
Reputation: 9905
Stumbled on this question while implementing a decorator. Putting it here for future reference:
class Decorator():
def __init__(self, seed):
self._seed = seed
def decorated(self):
return self
def __getattr__(self, attr):
return self._seed.__getattribute__(attr)
Python3 has hooks for both __getattr__
but only __getattribute__
is present by default (Why is object.__getattr__ missing?)
Upvotes: 0