ุงููุธุฑ ูู ุงูุชุนููู
ุงุช ุงูุจุฑู
ุฌูุฉ ุงูุชุงููุฉ:
class Foo: def __init__(self): self.bar = 'hello!' foo = Foo() print(foo.bar)
ุงูููู
ุณูู ูุญูู ุงูุฅุฌุงุจุฉ ุนูู ุงูุณุคุงู: "ู
ุงุฐุง ูุญุฏุซ ุจุงูุถุจุท ุนูุฏู
ุง ููุชุจ foo.bar ุ"
ุฑุจู
ุง ุชุนูู
ุจุงููุนู ุฃู ู
ุนุธู
ุงููุงุฆูุงุช ุชุญุชูู ุนูู ูุงู
ูุณ __dict__ ุฏุงุฎูู ูุญุชูู ุนูู ุฌู
ูุน ุณู
ุงุชูุง. ูู
ุง ูุจุนุซ ุนูู ุงูุณุฑูุฑ ุจุดูู ุฎุงุต ูู ู
ุฏู ุณูููุฉ ุฏุฑุงุณุฉ ู
ุซู ูุฐู ุงูุชูุงุตูู ู
ูุฎูุถุฉ ุงูู
ุณุชูู ูู ุจูุซูู:
>>> foo = Foo() >>> foo.__dict__ {'bar': 'hello!'}
ููุจุฏุฃ ุจู
ุญุงููุฉ ุตูุงุบุฉ ูุฐู ุงููุฑุถูุฉ (ุบูุฑ ุงูู
ูุชู
ูุฉ):
foo.bar ู
ูุงูุฆ ูู foo .__ dict __ ['bar'] .
ูู ุญูู ูุจุฏู ู
ุซู ุงูุญูููุฉ:
>>> foo = Foo() >>> foo.__dict__['bar'] 'hello!'
ูููุชุฑุถ ุงูุขู ุฃูู ุชุฏุฑู ุจุงููุนู ุฃูู ูู
ูู ุชุนุฑูู ุงูุณู
ุงุช ุงูุฏููุงู
ูููุฉ ูู ุงููุตูู ุงูุฏุฑุงุณูุฉ:
>>> class Foo: ... def __init__(self): ... self.bar = 'hello!' ... ... def __getattr__(self, item): ... return 'goodbye!' ... ... foo = Foo() >>> foo.bar 'hello!' >>> foo.baz 'goodbye!' >>> foo.__dict__ {'bar': 'hello!'}
ุญุณููุง ... ุญุณููุง. ูู
ูู ู
ูุงุญุธุฉ ุฃู __getattr__ ูู
ูู ุฃู ุชุญุงูู ุงููุตูู ุฅูู ุงูุณู
ุงุช "ุงูู
ุฒููุฉ" ุ ููููุง ูู ุชุนู
ู ุฅุฐุง ูุงู ููุงู ุจุงููุนู ู
ุชุบูุฑ ู
ูุนูู (ู
ุซู foo.bar ููุฑุฌุน "ู
ุฑุญุจูุง!" ูููุณ "ูุฏุงุนูุง!" ). ูุจุฏู ุฃู ูู ุดูุก ุฃูุซุฑ ุชุนููุฏูุง ู
ู
ุง ุจุฏุง ูู ุงูุจุฏุงูุฉ.
ูุจุงููุนู: ููุงู ุทุฑููุฉ ุณุญุฑูุฉ ุชุณู
ู ููู
ุง ุญุงูููุง ุงูุญุตูู ุนูู ุณู
ุฉ ุ ูููู ุ ูู
ุง ูู ู
ูุถุญ ุฃุนูุงู ุ ููุณุช ูุฐู __getattr__ . ุชุณู
ู ุงูุทุฑููุฉ ุงูุชู ูุทูู ุนูููุง __getattribute__ ุ ูุณูุญุงูู ููู
ููู ุชุนู
ู ุจุงูุถุจุท ู
ู ุฎูุงู ู
ุฑุงูุจุฉ ุงูู
ูุงูู ุงูู
ุฎุชููุฉ.
ุญุชู ุงูุขู ุ ูููู
ุจุชุนุฏูู ูุฑุถูุชูุง ุนูู ุงููุญู ุงูุชุงูู:
foo.bar ู
ูุงูุฆ ูู foo .__ getattribute __ ('bar') ุ ูุงูุฐู ูุนู
ู ุชูุฑูุจูุง ู
ุซู ูุฐุง:
def __getattribute__(self, item): if item in self.__dict__: return self.__dict__[item] return self.__getattr__(item)
ุณูุฎุชุจุฑูุง ุนู ุทุฑูู ุชุทุจูู ูุฐู ุงูุทุฑููุฉ (ุชุญุช ุงุณู
ู
ุฎุชูู) ููุทูู ุนูููุง ู
ุจุงุดุฑุฉ:
>>> class Foo: ... def __init__(self): ... self.bar = 'hello!' ... ... def __getattr__(self, item): ... return 'goodbye!' ... ... def my_getattribute(self, item): ... if item in self.__dict__: ... return self.__dict__[item] ... return self.__getattr__(item) >>> foo = Foo() >>> foo.bar 'hello!' >>> foo.baz 'goodbye!' >>> foo.my_getattribute('bar') 'hello!' >>> foo.my_getattribute('baz') 'goodbye!'
ูุจุฏู ุตุญูุญุง ุ ุฃููุณ ูุฐููุ
ุญุณููุง ุ ูู ู
ุง ุชุจูู ูู ุงูุชุญูู ู
ู ุฃู ู
ูู
ุฉ ุงูู
ุชุบูุฑุงุช ู
ุฏุนูู
ุฉ ุ ูุจุนุฏ ุฐูู ูู
ููู ุงูุนูุฏุฉ ุฅูู ุงูู
ูุฒู ... -
>>> foo.baz = 1337 >>> foo.baz 1337 >>> foo.my_getattribute('baz') = 'h4x0r' SyntaxError: can't assign to function call
ูุนูุฉ.
ุฅุฑุฌุงุน my_getattribute ูุงุฆู. ูู
ูููุง ุชุบููุฑู ุฅุฐุง ูุงู ูุงุจูุงู ููุชุบููุฑ ุ ููู ูุง ูู
ูููุง ุงุณุชุจุฏุงูู ุจู
ุณุชุฎุฏู
ุขุฎุฑ ุจุงุณุชุฎุฏุงู
ู
ุดุบู ุงูู
ูู
ุฉ. ู
ุงุฐุง ุชูุนูุ ุจุนุฏ ูู ุดูุก ุ ุฅุฐุง ูุงู foo.baz ู
ูุงูุฆูุง ูุงุณุชุฏุนุงุก ุฏุงูุฉ ุ ูููู ูู
ูููุง ุชุนููู ููู
ุฉ ุฌุฏูุฏุฉ ูุณู
ุฉ ู
ู ุญูุซ ุงูู
ุจุฏุฃุ
ุนูุฏู
ุง ููุธุฑ ุฅูู ุชุนุจูุฑ ู
ุซู foo.bar = 1 ุ ููุงู ู
ุง ูู ุฃูุซุฑ ู
ู ู
ุฌุฑุฏ ุงุณุชุฏุนุงุก ุฏุงูุฉ ููุญุตูู ุนูู ููู
ุฉ foo.bar . ูุจุฏู ุฃู ุชุนููู ููู
ุฉ ุฅูู ุณู
ุฉ ูุฎุชูู ุงุฎุชูุงููุง ุฃุณุงุณููุง ุนู ุงูุญุตูู ุนูู ููู
ุฉ ุณู
ุฉ. ูุงูุญูููุฉ: ูู
ูููุง ุชูููุฐ __setattr__ ูุฑุคูุฉ ูุฐุง:
>>> class Foo: ... def __init__(self): ... self.__dict__['my_dunder_dict'] = {} ... self.bar = 'hello!' ... ... def __setattr__(self, item, value): ... self.my_dunder_dict[item] = value ... ... def __getattr__(self, item): ... return self.my_dunder_dict[item] >>> foo = Foo() >>> foo.bar 'hello!' >>> foo.bar = 'goodbye!' >>> foo.bar 'goodbye!' >>> foo.baz Traceback (most recent call last): File "<pyshell#75>", line 1, in <module> foo.baz File "<pyshell#70>", line 10, in __getattr__ return self.my_dunder_dict[item] KeyError: 'baz' >>> foo.baz = 1337 >>> foo.baz 1337 >>> foo.__dict__ {'my_dunder_dict': {'bar': 'goodbye!', 'baz': 1337}}
ููุงู ุฃู
ุฑุงู ูุฌุจ ู
ูุงุญุธุชูู
ุง ุจุฎุตูุต ูุฐุง ุงูุฑู
ุฒ:
- __setattr__ ูุง ููุฌุฏ ูุฏูู ูุธูุฑ __getattribute__ (ุฃู ุ ุทุฑููุฉ __setattribute__ ุงูุณุญุฑูุฉ ุบูุฑ ู
ูุฌูุฏุฉ).
- ูุชู
ุงุณุชุฏุนุงุก __setattr__ ุฏุงุฎู __init__ ุ ููุฐุง ูู ุงูุณุจุจ ูู ุฃููุง ู
ุฌุจุฑูู ุนูู ูุนู ุงูุฐุงุช. __ dict __ ['my_dunder_dict'] = {} ุจุฏูุงู ู
ู self.my_dunder_dict = {} . ุฎูุงู ุฐูู ุ ุณููุงุฌู ุงูุนูุฏูุฉ ูุงููุงุฆูุฉ.
ูููู ูุฏููุง ุฃูุถุง ุงูู
ูููุฉ (ูุฃุตุฏูุงุฆู). ุฏูููุฑ ูุณู
ุญ ููุทุฑู ุฃู ุชุนู
ู ูุณู
ุงุช.
ุฏุนููุง ูุญุงูู ุฃู ูููู
ููู ูุญุฏุซ ูุฐุง.
>>> class Foo(object): ... def __getattribute__(self, item): ... print('__getattribute__ was called') ... return super().__getattribute__(item) ... ... def __getattr__(self, item): ... print('__getattr__ was called') ... return super().__getattr__(item) ... ... @property ... def bar(self): ... print('bar property was called') ... return 100 >>> f = Foo() >>> f.bar __getattribute__ was called bar property was called
ููู
ุชุนุฉ ููุท ุ ู
ุงุฐุง ูุฏููุง ูู f .__ dict__ ุ
>>> f.__dict__ __getattribute__ was called {}
ูุง ููุฌุฏ ู
ูุชุงุญ ุดุฑูุท ูู __dict__ ุ ููู __getattr__ ูุง ูุชู
ุงุณุชุฏุนุงุกู ูุณุจุจ ู
ุง. WATุ
bar ูู ุทุฑููุฉ ุชุฃุฎุฐ ููุณูุง ูู
ุนูู
ุฉ ุ ููุฐู ุงูุทุฑููุฉ ูู ููุท ูู ุงููุตู ุงูุฏุฑุงุณู ุ ูููุณ ูู ู
ุซูู ุงููุฆุฉ. ููุฐุง ู
ู ุงูุณูู ุฃู ูุฑู:
>>> Foo.__dict__ mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__getattr__': <function Foo.__getattr__ at 0x038308A0>, '__getattribute__': <function Foo.__getattribute__ at 0x038308E8>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'bar': <property object at 0x0381EC30>})
ู
ูุชุงุญ ุงูุดุฑูุท ู
ูุฌูุฏ ุจุงููุนู ูู ูุงู
ูุณ ุณู
ุฉ ุงููุตู. ูููู
ููู ูุนู
ู __getattribute__ ุ ูุญุชุงุฌ ุฅูู ุงูุฅุฌุงุจุฉ ุนูู ุงูุณุคุงู: ู
ู ุงูุฐู __getattribute__ ูุณู
ู ู
ู ูุจู - ูุฆุฉ ุฃู
ู
ุซููุ
>>> f.__dict__['bar'] = 'will we see this printed?' __getattribute__ was called >>> f.bar __getattribute__ was called bar property was called 100
ูู
ูู ู
ูุงุญุธุฉ ุฃู ุฃูู ุดูุก ูุชู
ุงูุชุญูู ู
ูู ูู ูุฆุฉ __dict__ ุ ุฃู ููุง ุฃููููุฉ ุนูู ุงูู
ุซุงู.
ุงูุชุธุฑ ูุญุธุฉ ุ ู
ุชู ุงุชุตููุง ุจุทุฑููุฉ ุงูุจุงุฑ ุ ุฃูุตุฏ ุ ุงูููุฏ ุงูุฒุงุฆู ุงูุฎุงุต ุจูุง ูู __getattribute__ ูุง ูุณุชุฏุนู ูุงุฆููุง ุฃุจุฏูุง. ู
ุง ุงูุฐู ูุญุฏุซุ
ุชูุจูุฉ ุจุฑูุชูููู ูุงุตู :
descr .__ get __ (selfุ objุ type = None) -> value
descr .__ set __ (selfุ objุ value) -> None
descr .__ delete __ (selfุ obj) -> None
ุจูุช ุงููุตูุฏ ููุง. ูู
ุจุชุทุจูู ุฃู ู
ู ูุฐู ุงูุทุฑู ุงูุซูุงุซ ุจุญูุซ ูุตุจุญ ุงููุงุฆู ูุงุตููุง ููู
ููู ุชุบููุฑ ุงูุณููู ุงูุงูุชุฑุงุถู ุนูุฏ ุงูุชุนุงู
ู ู
ุนู ูุณู
ุฉ.
ุฅุฐุง ุฃุนูู ูุงุฆู ุนู __get __ () ู __set __ () ุ ูุณูุทูู ุนููู ูุงุตู ุงูุจูุงูุงุช. ุชุณู
ู ูุงุตูุงุช ุชุทุจูู ููุท __get __ () ูุงุตูุงุช ุบูุฑ ุงูุจูุงูุงุช.
ูุฎุชูู ููุง ุงูููุนูู ู
ู ุงููุงุตูุงุช ูู ููููุฉ ุงููุชุงุจุฉ ููู ุนูุงุตุฑ ูุงู
ูุณ ุณู
ุฉ ุงููุงุฆู. ุฅุฐุง ูุงู ุงููุงู
ูุณ ูุญุชูู ุนูู ู
ูุชุงุญ ูุญู
ู ููุณ ุงุณู
ูุงุตู ุงูุจูุงูุงุช ุ ูุฅู ูุงุตู ุงูุจูุงูุงุช ูููู ูู ุงูุฃุณุจููุฉ (ุฃู ุ __set __ () ูุณู
ู). ุฅุฐุง ูุงู ุงููุงู
ูุณ ูุญุชูู ุนูู ู
ูุชุงุญ ูุญู
ู ููุณ ุงุณู
ุงููุงุตู ุจุฏูู ุจูุงูุงุช ุ ูุณูููู ูููุงู
ูุณ ุงูุฃููููุฉ (ุฃู ุ ุชุชู
ุงููุชุงุจุฉ ููู ุนูุตุฑ ุงููุงู
ูุณ).
ูุฅูุดุงุก ูุงุตู ุจูุงูุงุช ูููุฑุงุกุฉ ููุท ุ ูู
ุจุชุนุฑูู ูู ู
ู __get __ () ู __set __ () ุ ุญูุซ ูุฑู
ู __set __ () ุนูู AttributeError ุนูุฏ ุงูุงุชุตุงู ุจู. ุชุทุจูู __set __ () ูุฐุง ูููู ูุฅูุดุงุก ูุงุตู ุจูุงูุงุช.
ุจุงุฎุชุตุงุฑ ุ ุฅุฐุง ุฃุนููุช ุฃููุง ู
ู ูุฐู ุงูุทุฑู __get__ ุฃู __set__ ุฃู __delete__ ุ ูุฃูุช ุชููุฐ ุงูุฏุนู
ูุจุฑูุชูููู ุงููุงุตู. ููุฐุง ูู ุจุงูุถุจุท ู
ุง ููุนูู ู
ุตู
ู
ุงูู
ู
ุชููุงุช : ููู ูุนูู ุนู ูุงุตู ูููุฑุงุกุฉ ููุท ุณูุชู
ุงุณุชุฏุนุงุคู ูู __getattribute__ .
ุขุฎุฑ ุชุบููุฑ ูู ุชุทุจูููุง:
foo.bar ู
ูุงูุฆ ูู foo .__ getattribute __ ('bar') ุ ูุงูุฐู ูุนู
ู ุชูุฑูุจูุง ู
ุซู ูุฐุง:
def __getattribute__(self, item): if item in self.__class__.__dict__: v = self.__class__.__dict__[item] elif item in self.__dict__: v = self.__dict__[item] else: v = self.__getattr__(item) if hasattr(v, '__get__'): v = v.__get__(self, type(self)) return v
ุฏุนูุง ูุญุงูู ุงูุชูุถูุญ ูู ุงูู
ู
ุงุฑุณุฉ:
class Foo: class_attr = "I'm a class attribute!" def __init__(self): self.dict_attr = "I'm in a dict!" @property def property_attr(self): return "I'm a read-only property!" def __getattr__(self, item): return "I'm dynamically returned!" def my_getattribute(self, item): if item in self.__class__.__dict__: print('Retrieving from self.__class__.__dict__') v = self.__class__.__dict__[item] elif item in self.__dict__: print('Retrieving from self.__dict__') v = self.__dict__[item] else: print('Retrieving from self.__getattr__') v = self.__getattr__(item) if hasattr(v, '__get__'): print("Invoking descriptor's __get__") v = v.__get__(self, type(self)) return v
>>> foo = Foo() ... ... print(foo.class_attr) ... print(foo.dict_attr) ... print(foo.property_attr) ... print(foo.dynamic_attr) ... ... print() ... ... print(foo.my_getattribute('class_attr')) ... print(foo.my_getattribute('dict_attr')) ... print(foo.my_getattribute('property_attr')) ... print(foo.my_getattribute('dynamic_attr')) I'm a class attribute! I'm in a dict! I'm a read-only property! I'm dynamically returned! Retrieving from self.__class__.__dict__ I'm a class attribute! Retrieving from self.__dict__ I'm in a dict! Retrieving from self.__class__.__dict__ Invoking descriptor's __get__ I'm a read-only property! Retrieving from self.__getattr__ I'm dynamically returned!

ูุญู ููุท ุฎุฏุด ุณุทุญ ุชูููุฐ ุงูุณู
ุฉ ูู ุจูุซูู ููููุง. ุนูู ุงูุฑุบู
ู
ู ุฃู ุงูู
ุญุงููุฉ ุงูุฃุฎูุฑุฉ ูู
ุญุงูุงุฉ foo.bar ุตุญูุญุฉ ุจุดูู ุนุงู
ุ ุถุน ูู ุงุนุชุจุงุฑู ุฃูู ูุฏ ุชููู ููุงู ุฏุงุฆู
ูุง ุชูุงุตูู ุตุบูุฑุฉ ูุชู
ุชูููุฐูุง ุจุทุฑููุฉ ู
ุฎุชููุฉ.
ุขู
ู ุฃูู ุจุงูุฅุถุงูุฉ ุฅูู ู
ุนุฑูุฉ ููููุฉ ุนู
ู ุงูุณู
ุงุช ุ ุชู
ููุช ุฃูุถูุง ู
ู ุฅูุตุงู ุฌู
ุงู ุงููุบุฉ ุงูุชู ุชุดุฌุนู ุนูู ุงูุชุฌุฑุจุฉ. ุณุฏุงุฏ ุจุนุถ ุฏููู ุงูู
ุนุฑูุฉ ุงูููู
.