【问题标题】:use one function to getattr for either functions or regular attributes使用一个函数来获取函数或常规属性的属性
【发布时间】:2016-04-04 19:48:46
【问题描述】:

我有以下代码:

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

有没有一种更短、更易于维护的方法来制作这样的函数?谢谢。

【问题讨论】:

    标签: python python-3.x getattr getattribute


    【解决方案1】:

    解决方案 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
    

    【讨论】:

    • 我无法更改我正在尝试调用的函数
    • 你是指函数set_session_attribute还是类Thing中的方法或其他函数?
    • 我无法更改正在访问的类中的任何内容,例如 Thing(),一个庞大的系统依赖于这些
    • 添加了第二个不需要更改Thing的解决方案。
    • if/return 比我昨天结束的要好。 ty
    【解决方案2】:

    @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) 之类的东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 2023-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多