2015-11-15 1 views
0

J'ai une classe de base qui a 2 attributs qui sont eux-mêmes d'une autre classe. Voir le code ci-dessousFonction __getattribute__ pour renvoyer la valeur d'objet d'une autre classe

class Base(object): 
    def __init__(self, obj1, obj2): 
     self.obj1 = obj1 
     self.obj2 = obj2 

    def __getattribute__(self, name): 
     #import pdb; pdb.set_trace() 
     if name == 'obj1': 
      obj = object.__getattribute__(self, name) #self.obj1.value 
      return object.__getattribute__(obj,'value') 

class Temp(object): 
    def __init__(self, value, type): 
     self.value = value 
     self.type = type 

    def __getattribute__(self, name): 
     #if name == 'value': 
     # return object.__getattribute__(self, name) 
     if name == 'type': 
      return object.__getattribute__(self, name) 

if __name__ == "__main__": 
    temp_obj1 = Temp(45, type(45)) 
    temp_obj2 = Temp('string', type('string')) 

    base_obj = Base(temp_obj1, temp_obj2) 
    print base_obj.obj1 
    print base_obj.obj1.type 

et sa sortie: -

45 
Traceback (most recent call last): 
    File "getattr.py", line 29, in <module> 
    print base_obj.obj1.type 
AttributeError: 'int' object has no attribute 'type' 

En fait ce que je suis en train de réaliser est que je n'ai pas appeler base_obj.obj1.value pour obtenir l'attribut value de obj1 mais appelant base_obj.obj1 sera donne le résultat désiré. Mais en même temps, je suis en mesure d'appeler une fonction ou une propriété de obj1 comme base_obj.obj1.type ou base_obj.obj1.some_method()

Mais comme vous pouvez le voir, je reçois l'erreur. Comment puis-je obtenir la fonctionnalité souhaitée

Répondre

1

Si je comprends bien votre question, vous ne pouvez pas faire ce que vous essayez de faire, et de plus, vous ne devriez pas vraiment. Quel que soit base_obj.obj1 est, base_obj.obj1.type obtiendra l'attribut type de cela, parce base_obj.obj1.type signifie (base_obj.ob1).type --- c'est-à-dire, il évalue l'attribut obj1 d'abord. Il n'y a aucun moyen de faire base_obj.obj1 retourner une chose, mais avoir la partie base_obj.obj1 de base_obj.obj1.type être quelque chose de différent. Au moment où la recherche de obj1 se produit, vous ne savez pas si une autre recherche d'attribut va avoir lieu plus tard.

Il y a de bonnes raisons à cela. Il serait très déroutant si ceux-ci ont donné des résultats différents:

# 1 
x = base_obj.obj1.type 

# 2 
tmp = base_obj.obj1 
x = tmp.type 

Si vous souhaitez obtenir l'attribut value, obtenir l'attribut value. Si vous voulez utiliserobj1 dans diverses situations comme si c'était son attribut de valeur, vous pouvez peut-être réaliser ce que vous voulez en surchargeant diverses opérations sur obj1 (de sorte que, par exemple, base_obj.obj1 + 2 fonctionne).