Что __setattr__ делает в этом коде Python? - PullRequest
2 голосов
/ 19 марта 2011

это мой код:

class fun:

    def __getattr__(self,key):
        return self[key]

    def __setattr__(self,key,value):
        self[key] = value+1
a = fun()
a['x']=1
print a['x']

и ошибка:

AttributeError: fun instance has no attribute '__getitem__'

когда я изменяю его на:

class fun:

    def __getattr__(self,key):
        return self.key

    def __setattr__(self,key,value):
        self.key = value+1
a = fun()
a.x=1
print a.x

ошибка:

RuntimeError: maximum recursion depth exceeded

что я могу сделать, я хочу получить 2

Ответы [ 3 ]

7 голосов
/ 19 марта 2011

Проблема в том, что self.key = ... вызывает __setattr__, так что вы попадаете в бесконечную рекурсию. Чтобы использовать __setattr__, вам нужно получить доступ к полю объекта другим способом. Есть два общих решения:

def __setattr__(self,key,value):
    # Access the object's fields through the special __dict__ field
    self.__dict__[key] = value+1

# or...

def __init__(self):
    # Assign a dict field to access fields set via __[gs]etattr__
    self.attrs = {}

def __setattr__(self,key,value):
    self.attrs[key] = value+1
3 голосов
/ 19 марта 2011

Это опечатка.

Вы хотите реализовать специальный метод __setattr__, а не __serattr__, который не имеет особого значения.

1 голос
/ 19 марта 2011

Во-первых, метод называется __setattr__(). Это когда попытка присвоения атрибута. Например, когда вы делаете:

self[key] = value+1

... сделать ваш конкретный вызов (бесконечно) рекурсивным!

Лучший способ сделать это - извлечь ваш класс из object, так называемого класса нового стиля и вызвать базовый класс:

class fun(object):

    def __setattr__(self,key,value):
        super(fun, self).__setattr__(key, value + 1)

a = fun()
a.x=1
print a.x

Я удалил вашу __getattr__() реализацию, так как она ничего не сделала.

...