lst = [1, 2, 3]
if 1 in lst:
...
то в случае ассоциации ссылка на экземпляр другого класса используется без отношения включения одного в другой или принадлежности. О таком отношении между классами говорят как об отношении USE–A («ИСПОЛЬЗУЕТ»). Это достаточно общее отношение зависимости между классами.
В языке Python границы между агрегацией и ассоциацией несколько размыты, так как объекты при агрегации обычно не хранятся в области памяти, выделенной под контейнер (хранятся только ссылки).
Объекты могут также ссылаться друг на друга. В этом случае возникают циклические ссылки, которые при неаккуратном использовании могут привести (в старых версиях Python) к утечкам памяти. В новых версиях Python для циклических ссылок работает сборщик мусора.
Разумеется, при «чистой» агрегации циклических ссылок не возникает.
Например, при представлении дерева ссылки могут идти от родителей к детям и обратно от каждого дочернего узла к родительскому.
Слабые ссылки
Для обеспечения ассоциаций объектов без свойственных ссылкам проблем с возможностью образования циклических ссылок, в Python для сложных структур данных и других видов использования, при которых ссылки не должны мешать удалению объекта, предлагается механизм слабых ссылок. Такая ссылка не учитывается при подсчете ссылок на объект, а значит, объект удаляется с исчезновением последней «сильной» ссылки.
Для работы со слабыми ссылками применяется модуль weakref. Основные принципы его работы станут понятны из следующего примера:
>>> import weakref
>>>
>>> class MyClass(object):
... def __str__(self):
... return "MyClass"
...
>>>
>>> s = MyClass() # создается экземпляр класса
>>> print s
MyClass
>>> s1 = weakref.proxy(s) # создается прокси–объект
>>> print s1 # прокси–объект работает как исходный
MyClass
>>> ss = weakref.ref(s) # создается слабая ссылка на него
>>> print ss() # вызовом ссылки получается исходный объект
MyClass
>>> del s # удаляется единственная сильная ссылка на объект
>>> print ss() # теперь исходного объекта не существует
None
>>> print s1
Traceback (most recent call last):
File "", line 1, in ?
ReferenceError: weakly–referenced object no longer exists
К сожалению, поведение прокси–объекта не совсем такое, как у исходного: он не может быть ключом словаря, так как является нехэшируемым.
Иногда необходимо использовать метод, принадлежащий классу, а не его экземпляру. В этом случае можно описать статический метод. До появления декораторов (до Python 2.4) определять статический метод приходилось следующим образом:
class A(object):
def name():
return A.__name__
name = staticmethod(name)
print A.name()
a = A()
print a.name()
Статическому методу не передается параметр с экземпляром класса. Он ему попросту не нужен.
В Python 2.4 для применения описателей (descriptors) был придуман новый синтаксис — декораторы:
class A(object):
@staticmethod
def name():
return A.__name__
Смысл декоратора в том, что он «пропускает» определяемую функцию (или метод) через заданную в нем функцию. Теперь писать name три раза не потребовалось. Декораторов может быть несколько, и применяются они в обратном порядке.
Если статический метод имеет свои аналоги в C++ и Java, то метод класса основан на том, что в Python классы являются объектами. В отличие от статического метода, в метод класса первым параметром передается объект–класс. Вместо selfдля подчеркивания принадлежности метода к методам класса принято использовать cls.
Пример использования метода класса можно найти в модуле treeпакета nltk(Natural Language ToolKit, набор инструментов для естественного языка). Ниже приведен лишь фрагмент определения класса Tree(базового класса для других подклассов). Метод convertкласса Treeопределяет процедуру преобразования дерева одного типа в дерево другого типа. Эта процедура абстрагируется от деталей реализации конкретных типов, описывая обобщенный алгоритм преобразования:
class Tree:
# ...
def convert(cls, val):
if isinstance(val, Tree):
children = [cls.convert(child) for child in val]
return cls(val.node, children)
else:
return val
convert = classmethod(convert)
Читать дальше
Конец ознакомительного отрывка
Купить книгу