使用一个函数来获取函数或常规属性的attr



我有以下代码:

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 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

所以这是一个吸气器。还有一个setter @property.setter,您可以在其中执行t.length = somedata,而不是类似t.set_length(somedata)

最新更新