使用一个函数来获取函数或常规属性的属性
use one function to getattr for either functions or regular attributes
我有以下代码:
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
这是因为调用 "length()"
无效 (AttributeError, no attribute length()
)
有没有更短、更易于维护的方法来制作这样的函数?谢谢。
解决方案 1
您可以将 length
设为 property
:
class Thing(object):
def __init__(self):
self.legs = 4
@property
def length(self):
return 6
>>> thing = Thing()
>>> thing.legs
4
>>> thing.length
6
如果你真的想使用你的功能:
def set_session_attribute(obj, attribute):
return getattr(obj, attribute)
>>> set_session_attribute(thing, 'legs')
4
>>> set_session_attribute(thing, 'length')
6
如果您不能直接更改 thing
的来源,您可以在导入 class:
class Thing(object):
def __init__(self):
self.legs = 4
def length(self):
return 6
这里:
Thing.length2 = property(Thing.length)
>>> thing = Thing()
>>> thing.length2
6
解决方案 2
或者,您可以检查属性是否可调用:
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
用 @property
装饰那些方法,您认为它们应该具有数据语义而不是方法。
class Thing:
@property
def length(self):
return somedata
@property.setter
def length(self, value):
somename = value
t = Thing()
l0 = t.length
t.length = l1
所以这是 getter。还有一个 setter @property.setter
,您可以在其中执行 t.length = somedata
而不是 t.set_length(somedata)
我有以下代码:
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
这是因为调用 "length()"
无效 (AttributeError, no attribute length()
)
有没有更短、更易于维护的方法来制作这样的函数?谢谢。
解决方案 1
您可以将 length
设为 property
:
class Thing(object):
def __init__(self):
self.legs = 4
@property
def length(self):
return 6
>>> thing = Thing()
>>> thing.legs
4
>>> thing.length
6
如果你真的想使用你的功能:
def set_session_attribute(obj, attribute):
return getattr(obj, attribute)
>>> set_session_attribute(thing, 'legs')
4
>>> set_session_attribute(thing, 'length')
6
如果您不能直接更改 thing
的来源,您可以在导入 class:
class Thing(object):
def __init__(self):
self.legs = 4
def length(self):
return 6
这里:
Thing.length2 = property(Thing.length)
>>> thing = Thing()
>>> thing.length2
6
解决方案 2
或者,您可以检查属性是否可调用:
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
用 @property
装饰那些方法,您认为它们应该具有数据语义而不是方法。
class Thing:
@property
def length(self):
return somedata
@property.setter
def length(self, value):
somename = value
t = Thing()
l0 = t.length
t.length = l1
所以这是 getter。还有一个 setter @property.setter
,您可以在其中执行 t.length = somedata
而不是 t.set_length(somedata)