2016-04-04 16 views
2

Ich habe den folgenden Code:verwenden Sie eine Funktion entweder für Funktionen oder regelmäßige Attribute 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 

Dies, weil mit "length()" Aufruf ist nicht funktioniert (AttributeError, no attribute length())

Gibt es eine kürzere, Wartbare Möglichkeit, Funktionen wie diese zu machen? Vielen Dank.

Antwort

5

Lösung 1

Sie können length eine property machen:

class Thing(object): 
    def __init__(self): 
     self.legs = 4 
    @property 
    def length(self): 
     return 6 

>>> thing = Thing() 
>>> thing.legs 
4 
>>> thing.length 
6 

Wenn Sie wirklich Ihre Funktion verwenden möchten:

def set_session_attribute(obj, attribute): 
    return getattr(obj, attribute) 

>>> set_session_attribute(thing, 'legs') 
4 
>>> set_session_attribute(thing, 'length') 
6 

Wenn Sie nicht die Quelle der thing direkt ändern können, Sie können nach dem Importieren der Klasse tun:

Hier
class Thing(object): 
    def __init__(self): 
     self.legs = 4 
    def length(self): 
     return 6 

:

Thing.length2 = property(Thing.length) 

>>> thing = Thing() 
>>> thing.length2 
6 

Lösung 2

Alternativ können Sie überprüfen, ob das Attribut aufrufbar ist:

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

tun kann ich die Funktion nicht ändern kann ich versuche – codyc4321

+1

zu anrufen Haben Sie die Funktion 'set_session_attribute' oder eine Methode in der Klasse bedeutet' Thing 'oder eine andere Funktion? –

+0

Ich kann nichts in den Klassen ändern, auf die ich zugreife, wie Thing(), ein riesiges System hängt davon ab – codyc4321

1

diese Methoden Verzieren mit @property, die Sie Semantik fühlen von Daten und nicht von einer Methode.

class Thing: 
    @property 
    def length(self): 
     return somedata 

    @property.setter 
    def length(self, value): 
     somename = value 

t = Thing() 
l0 = t.length 
t.length = l1 

Also das ist ein Getter. Es gibt auch einen Setter @property.setter, wo man t.length = somedata statt so etwas wie t.set_length(somedata)