2016-04-04 1 views
2

Basé surne peut pas accéder à l'attribut w getattr d'un attribut?

In [65]: %paste 
class Thing(object): 
    def __init__(self, obj): 
     self.legs = 4 
     self.obj = obj 
    def length(self): 
     return 6 

class Thing2(object): 
    def __init__(self): 
     self.arms = 2 

## -- End pasted text -- 

In [66]: t = Thing2() 

In [67]: x = Thing(t) 

In [68]: x.obj.arms 
Out[68]: 2 

In [69]: %paste 
def set_session_attribute(obj, attribute): 
    if attribute.endswith('()'): 
     attribute = attribute.replace('()', '') 
     return getattr(obj, attribute)() 
    else: 
     return getattr(obj, attribute) 

## -- End pasted text -- 

In [70]: x = set_session_attribute(x, 'obj.arms') 
--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-70-f8cbad3c39e5> in <module>() 
----> 1 x = set_session_attribute(x, 'obj.arms') 

<ipython-input-69-65b6efa81583> in set_session_attribute(obj, attribute) 
     4   return getattr(obj, attribute)() 
     5  else: 
----> 6   return getattr(obj, attribute) 

AttributeError: 'Thing' object has no attribute 'obj.arms' 

Comment puis-je utiliser getattr pour trouver arms de l'objet t en une ligne? Merci

class Thing(object): 
    def __init__(self, obj): 
     self.legs = 4 
     self.obj = obj 

    def length(self): 
     return 6 

class Other(object): 
    def __init__(self): 
     self.arms = 2 

    def length(self): 
     return 5 


def set_session_attribute(obj, attribute): 
    attrs = attribute.split('.') 
    for attribute in attrs: 
     if attribute.endswith('()'): 
      attribute = attribute.replace('()', '') 
      obj = getattr(obj, attribute)() 
     else: 
      obj = getattr(obj, attribute) 
    return obj 

a = Other() # other has attr or function too 
b = Thing(a) # thing has other obj, attr, and its own function 

""" 
In [80]: b.obj.length() 
Out[80]: 5 

In [81]: b.obj.arms 
Out[81]: 2 

In [83]: b.length() 
Out[83]: 6 

In [84]: b.legs 
Out[84]: 4 
""" 

g = set_session_attribute(b, 'obj.length()') 
h = set_session_attribute(b, 'obj.arms') 
i = set_session_attribute(b, 'length()') 
j = set_session_attribute(b, 'legs') 
assert g == 5 
assert h == 2 
assert i == 6 
assert j == 4 
+0

' L'objet Thing a un attribut nommé "bras", pas "obj.arms". – martineau

+0

'obj.arms' n'est pas un attribut unique, c'est un attribut dans un attribut. – o11c

+1

A quoi sert cette fonction 'set_session_attribute'? Quels formats doit-il gérer? Vous avez posé une question à propos de l'obtention de 'x.foo()' et d'une question sur l'obtention de la fonction 'x.foo.bar' maintenant; si elle doit gérer des choses comme 'x.foo [3] ('asdf'). bar' ou' x.foo + 3', nous pourrions aussi bien l'enlever maintenant. – user2357112

Répondre

1

Vous pouvez essayer ceci:

def set_session_attribute(obj, attribute): 
     if attribute.endswith('()'): 
      attribute = attribute.replace('()', '') 
     attrs = attribute.split('.') 
     for attr in attrs: 
      obj = getattr(obj, attr) 
     return obj 
+1

à la fois bien, mais pas de raison de faire une fonction séparée s'il n'y a pas besoin – codyc4321

1

x.obj.arms équivaudrait à getattr(getattr(x, 'obj'), 'arms').

>>> x = Thing(Thing2()) 
>>> x.obj.arms 
2 
>>> getattr(getattr(x, 'obj'), 'arms') 
2 

Ou, à partir d'une instance de Thing2, vous devriez juste écrire

>>> t = Thing2() 
>>> getattr(t, 'arms') 
2 
1

Essayez ceci:

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

class Thing2(object): 
    def __init__(self): 
     self.arms = 2 

def recursiveAttr(obj, attribute): 
    attributeHierarchy = attribute.split('.') 
    for attr in attributeHierarchy: 
     obj = getattr(obj, attr) 
    return obj 

def get_session_attribute(obj, attribute): 
    if attribute.endswith('()'): 
     attribute = attribute.replace('()', '') 
     return recursiveAttr(obj, attribute)() 
    else: 
     return recursiveAttr(obj, attribute) 

t = Thing2() 
x = Thing(t) 
print get_session_attribute(x, 'obj.arms')