Специальные методы
В питоне есть несколько специальных встроенных методов .
Классы и обьекты
Пример:
class foo:
def __init__(self, n):
print 'Constructor called'
self.n = n
def hello(self):
print 'Hello world'
def change(self, n):
print 'Changing self.n'
self.n = n
f = foo(10) # создает обьект класса foo с членом 'n' = 10.
print f.n # печатает 10.
f.m = 20 # можно к обекту добавить новое поле !
f.hello() # печатает 'Hello world'
foo.change(f, 40)
print f.n # печатает 40
Метод __init__ похож на конструктор в C++.
Это - один из специальных методов , который вызывается
автоматически при создании обьекта.
Мы видим , что все методы имеют параметр 'self'.
И при вызове f.hello() параметром этого метода является обьект 'f'.
Вместо 'self' может стоять другое слово .
Возможно также вместо f.hello() вызвать foo.hello(f).
Есть определенная связь между 'self' и ключевым словом 'this'(в C++).
Специальный метод __add__
Рассмотрим пример:
class foo:
def __init__(self, n):
self.n = n
def __add__(self, right):
t = foo(0)
t.n = self.n + right.n
return t
Создадим 2 обьекта - f1 , f2 - и сложим их :
f1 = foo(10) # f1.n is 10
f2 = foo(20) # f2.n is 20
f3 = f1 + f2
print f3.n # prints 30
Что происходит при выполнении f1+f2 ? Фактически вызывается f1.__add__(f2).
Поэтому 'self' в функции __add__ ссылается на f1 и 'right' ссылается на f2.
Другой вариант __add__
Пример :
class foo:
def __init__(self, n):
self.n = n
def __radd__(self, left):
t = foo(0)
t.n = self.n + left.n
print 'left.n is', left.n
return t
f1 = foo(10)
f2 = foo(20)
f3 = f1 + f2 # печатает 'left.n is 10'
В данном случае f1+f2 конвертируется в f2.__radd__(f1).
Самораспечатка обьекта - метод __str__
class foo:
def __init__(self, n1, n2):
self.n1 = n1
self.n2 = n2
def __str__(self):
return 'foo instance:'+'n1='+`self.n1`+','+'n2='+`self.n2`
Класс foo определяет специальный метод __str__.
Пример:
f1 = foo(10,20)
print f1 # печатает 'foo instance: n1=10,n2=20'
Метод __nonzero__
__nonzero__ и __len__ реализованы для тестирования обьектов .
Пример :
class foo:
def __nonzero__(self):
return 0
class baz:
def __len__(self):
return 0
class abc:
pass
f1 = foo()
f2 = baz()
f3 = abc()
if (not f1): print 'foo: false' # печатает 'foo: false'
if (not f2): print 'baz: false' # печатает 'baz: false'
if (not f3): print 'abc: false' # ничего не печатает
Метод __getitem__
В списках с поддержкой индесации возможна операция типа 'print a[i]'.
В питоне есть специальный метод __getitem__ для поддержки
индексации пользовательских обьектов.
Пример:
class foo:
def __init__(self, limit):
self.limit = limit
def __getitem__(self, key):
if ((key > self.limit-1) or (key < -(self.limit-1))):
raise IndexError
else:
return 2*key
f = foo(10) # f acts like a 20 element array
print f[0], f[1] # prints 0, 2
print f[-3] # prints -6
print f[10] # generates IndexError
Есть еще несколько дополнительных методов :
__setitem__, __delitem__, __getslice__, __setslice__,
__delslice__ .
Метод __getattr__
__getattr__(self,name) позволяет обрабатывать исключения в том случае ,
когда нужный атрибут класса
не найден :
class foo:
def __getattr__(self, name):
return 'no such attribute'
f = foo()
f.n = 100
print f.n # prints 100
print f.m # prints 'no such attribute'
Имеется также встроенная функция getattr(object, name).
Так, getattr(f, 'n') вернет 100 и getattr(f,'m') вернет строку 'no such attribute'.
Следующий пример показывает реализацию делегирования :
class Boss:
def __init__(self, delegate):
self.d = delegate
def credits(self):
print 'I am the great boss, I did all that amazing stuff'
def __getattr__(self, name):
return getattr(self.d, name)
class Worker:
def work(self):
print 'Sigh, I am the worker, and I get to do all the work'
w = Worker()
b = Boss(w)
b.credits() # prints 'I am the great boss, I did all that amazing stuff'
b.work() # prints 'Sigh, I am the worker, and I get to do all the work'
Ссылки
Для начинающих хорошее руководство тут : tutorial.
Еще здесь : language reference
и здесь : library reference.
|
|