2012-03-17 2 views
1

Я использую классы «нового стиля» в Python 2.6, и у меня возникают проблемы с __getattr__ в подклассе.python __getattr__ и __name__

Если подкласс реализует, как например ...

def __getattr__(self, name): 
    if self.__folderDict.has_key(name): 
     if name == 'created': 
      return doSomethingSpecial(self.__folderDict[name]) 
     return self.__folderDict[name] 
    else: 
     raise AttributeError() 

Это мне не ясно, почему мое исключение атрибута выкинуто для ссылки на __name__?

Мое понимание заключается в том, что __getattr__ не должен даже вызываться и что __name__ должен быть заполнен __getattribute__, так как я использую новый стиль?

Вот более полный пример ...

class Base(object): 
    @staticmethod 
    def printMsg(msg, var): 
     print msg + str(var) 
     return 

    def printName(self): 
     Base.printMsg('#', self.__name__) 
     return 

class Derived(Base): 
    def __getattr__(self, name): 
     if self.__testDict.has_key(name): 
      return self.__testDict[name] 
     else: 
      raise AttributeError() 

    __testDict = {'userid': 4098} 


d = Derived() 
print d.userid 
d.printName() 

В результате ...

4098 
Traceback (most recent call last): 
File "D:/.../Scratch/scratch01.py", line 24, in <module> 
d.printName() 
File "D:/.../Scratch/scratch01.py", line 17, in __getattr__ 
raise AttributeError() 
AttributeError 
+2

Можете ли вы показать фактический код вызова и трассировку? – bgporter

+0

Согласитесь с прежним комментарием, ваша информация не очень детализирована и понятна, люди могут чувствовать смущение, когда хотят писать ответы. Но, по вашему пониманию __getattr__ и __getattribute__, [этот пост] (http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute-in-python) вам представляется полезным. – Reorx

+0

добавил еще один простой пример –

ответ

1

__name__ предопределен для объектов класса, а не экземпляров, и вы не определяете __name__ в любом месте, прежде чем пытаться его прочитать. Так вызывается _getattr__ (поскольку __name__ не может быть найден с помощью обычного поиска) и приводит к исключению. Я подозреваю, что вы действительно хотите:

... 
def printName(self): 
    Base.printMsg('#', self.__class__.__name__) 
    return 
... 
+0

Я этого не осознавал. Благодаря! –

-1

Edit: Ах, хорошо. Как сказал TokenMacGuy, getattr вызывается только тогда, когда поиск нормального атрибута не удался. Я попробовал, но забыл добавить атрибут __folderDict.

У вас есть свой собственный getattribute метод?

+1

er ... no .. '__getattr__' вызывается только тогда, когда ключ не найден с помощью обычного поиска атрибутов. только '__getattribute__' называется безоговорочно. – SingleNegationElimination

+0

Это было мое понимание - я не нахожусь в рекурсии здесь ... –

+0

, чтобы ответить на вышеупомянутый вопрос - я не переопределяю \ __ getattribute__ в подклассе –

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