I have the following code:
In [38]: %paste
def set_session_attribute(obj, attribute):
if attribute.endswith('()'):
attribute = attribute.replace('()', '')
return getattr(obj, attribute)()
else:
return getattr(obj, attribute)
class Thing(object):
def __init__(self):
self.legs = 4
def length(self):
return 6
## -- End pasted text --
In [39]: x = Thing()
In [40]: y = set_session_attribute(x, 'legs')
In [41]: y
Out[41]: 4
In [42]: z = set_session_attribute(x, 'length()')
In [43]: z
Out[43]: 6
This is because calling with "length()"
didn't work (AttributeError, no attribute length()
)
Is there a shorter, more maintainable way to make functions like this? Thank you.
You can make length
a property
:
class Thing(object):
def __init__(self):
self.legs = 4
@property
def length(self):
return 6
>>> thing = Thing()
>>> thing.legs
4
>>> thing.length
6
If you really want to use your function:
def set_session_attribute(obj, attribute):
return getattr(obj, attribute)
>>> set_session_attribute(thing, 'legs')
4
>>> set_session_attribute(thing, 'length')
6
If you cannot change the source of thing
directly, you can do after importing the class:
class Thing(object):
def __init__(self):
self.legs = 4
def length(self):
return 6
Here:
Thing.length2 = property(Thing.length)
>>> thing = Thing()
>>> thing.length2
6
Alternatively, you can check if the attribute is callable:
class Thing(object):
def __init__(self):
self.legs = 4
def length(self):
return 6
def set_session_attribute(obj, attribute):
attr = getattr(obj, attribute)
if hasattr(attr, '__call__'): # may use `callable()`
return attr()
return attr
>> thing = Thing()
>>> set_session_attribute(thing, 'legs')
4
>>> set_session_attribute(thing, 'length')
6