Також дозволяє це зробити: (коротше кажучи, виклик Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
поверне 12, але зробить це найвиразнішими способами.
class Outer(object):
def __init__(self, outer_num):
self.outer_num = outer_num
def create_inner_class(outer_self, inner_arg):
class Inner(object):
inner_arg = inner_arg
def weird_sum_with_closure_scope(inner_self, num)
return num + outer_self.outer_num + inner_arg
return Inner
Звичайно, це важче уявити в таких мовах, як Java та C #. Зробивши явну самопосилання, ви можете посилатися на будь-який об’єкт за допомогою цієї самонавірки. Крім того, такий спосіб гри з заняттями під час виконання важче зробити в більш статичних мовах - це не обов'язково добре чи погано. Просто явне «я» дозволяє всій цій божевільності існувати.
Більше того, уявіть собі це: ми хотіли б налаштувати поведінку методів (для профілювання чи божевільної чорної магії). Це може змусити нас задуматися: а якби у нас був клас Method
, поведінку якого ми могли б перекрити чи контролювати?
Ну ось це:
from functools import partial
class MagicMethod(object):
"""Does black magic when called"""
def __get__(self, obj, obj_type):
# This binds the <other> class instance to the <innocent_self> parameter
# of the method MagicMethod.invoke
return partial(self.invoke, obj)
def invoke(magic_self, innocent_self, *args, **kwargs):
# do black magic here
...
print magic_self, innocent_self, args, kwargs
class InnocentClass(object):
magic_method = MagicMethod()
А тепер: InnocentClass().magic_method()
діятиме так, як очікувалося. Метод буде пов'язаний з innocent_self
параметром до InnocentClass
і з magic_self
екземпляром MagicMethod. Дивно, так? Це як два ключові слова this1
та this2
такі мови, як Java та C #. Магія, як це, дозволяє рамкам робити речі, які інакше були б набагато більш багатослівними.
Знову ж таки, я не хочу коментувати етику цього матеріалу. Мені просто хотілося показати речі, які було б важче зробити без явного посилання на себе.
self
доступ до членів - stackoverflow.com/questions/910020/…