2016-04-04 2 views
2

я следующий код:использовать одну функцию GetAttr либо для функций или обычных атрибутов

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

Есть ли короче, удобный способ сделать такие функции? Спасибо.

ответ

5

Решение 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 
+0

Я не могу изменить функцию Я пытаюсь вызвать – codyc4321

+1

вы имеете в виду функцию 'set_session_attribute' или метод в классе' Thing 'или другую функцию? –

+0

Я ничего не могу изменить в классах, к которым я обращаюсь, таких как Thing(), огромная система зависит от этих – codyc4321

1

Украсьте эти методы с @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 

Так что это геттер. Существует также сеттер @property.setter, где вы можете сделать t.length = somedata вместо чего-то вроде t.set_length(somedata)

Смежные вопросы