Подтвердить что ты не робот

Какая связь между __getattr__ и getattr?

Я знаю, что этот код прав:

class A:   
    def __init__(self):
        self.a = 'a'  
    def method(self):   
        print "method print"  

a = A()   
print getattr(a, 'a', 'default')   
print getattr(a, 'b', 'default')  
print getattr(a, 'method', 'default') 
getattr(a, 'method', 'default')()   

И это неправильно

# will __getattr__ affect the getattr?

class a(object):
    def __getattr__(self,name):
        return 'xxx'

print getattr(a)

Это тоже неправильно:

a={'aa':'aaaa'}
print getattr(a,'aa')

Где мы должны использовать __getattr__ и getattr?

4b9b3361

Ответ 1

Ответ Alex был хорошим, но предоставил вам пример кода, так как вы его просили:)

class foo:
    def __init__(self):
        self.a = "a"
    def __getattr__(self, attribute):
        return "You asked for %s, but I'm giving you default" % attribute


>>> bar = foo()
>>> bar.a
'a'
>>> bar.b
"You asked for b, but I'm giving you default"
>>> getattr(bar, "a")
'a'
>>> getattr(bar, "b")
"You asked for b, but I'm giving you default"

Так что в коротком ответе

Вы используете

__getattr__ определить как обрабатывать атрибуты не найдены

и

getattr до получить атрибуты

Ответ 2

getattr - это встроенная функция, берущая (по крайней мере) два аргумента: объект, из которого вы получаете атрибут, и имя строки атрибута.

Если имя строки является константой, скажем 'foo', getattr(obj, 'foo') является точно такой же как obj.foo.

Итак, основной вариант использования встроенной функции getattr - это когда у вас нет имени атрибута как константы, а скорее как переменной. Второй важный вариант использования - когда вы передаете ему три аргумента, а не только два: в этом случае, если атрибут отсутствует в объекте, getattr возвращает третий аргумент "default", а не создает исключение.

__getattr__ - специальный метод, определенный в классе, который вызывается, когда запрашивается какой-либо атрибут экземпляра этого класса, и другие обычные способы доставки этого атрибута (через экземпляр __dict__, слоты, свойства, и т.д.) все провалилось. Вы можете определить его, например, когда вы хотите делегировать поиск атрибутов в противном случае undefined для других объектов.

Итак, ваш второй пример неверен, потому что встроенный getattr может вызывать никогда с помощью одного аргумента.

Третий не удается, потому что словарь, который вы пытаетесь получить из атрибута, не имеет этого атрибута - он имеет элементы, которые, конечно, полностью не пересекаются с атрибутами.

Ответ 3

__getattr__() - специальная функция метода, которую вы можете определить. Когда поиск элемента не выполняется, эта функция будет вызвана.

getattr() - это функция, которую вы можете вызвать, чтобы попытаться найти элемент. Если поиск выполняется успешно, вы получаете член (возможно, объект функции метода или, возможно, объект атрибута данных). getattr() также может возвращать значение по умолчанию в случае сбоя поиска.

Если вы объявляете функцию-член __getattr__(), вы можете сделать ее успешной, или вы можете сделать ее успешной каждый раз.

class A(object):
    def __getattr__(self, name):
        return "I pretend I have an attribute called '%s'" % name

a = A()

print a.foo # prints "I pretend I have an attribute called 'foo'"

Python также имеет __getattribute__(), который всегда вызывается при каждом поиске. Это очень опасно, потому что это может сделать невозможным доступ к членам в обычном режиме.

class A(object):
    def __init__(self, value):
        self.v = value
    def __getattribute__(self, name):
        return "I pretend I have an attribute called '%s'" % name

a = A(42)

print a.v # prints "I pretend I have an attribute called 'v'"
print a.__dict__["v"] # prints "I pretend I have an attribute called '__dict__'"

К сожалению, теперь невозможно получить доступ к a.v!