рдкрд╛рдпрдерди рдореЗрдВ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдФрд░ рд╕рдВрднрд╛рд▓рдирд╛

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


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 .__ рдХреЗ рд╕рдорд╛рди рд╣реИред рд╣реБрдХреБрдо __ ['рдмрд╛рд░'] ред


рдЬрдмрдХрд┐ рдпрд╣ рд╕рдЪ рд▓рдЧрддрд╛ рд╣реИ:


 >>> 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 __ ('рдмрд╛рд░') рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдЬреЛ рд▓рдЧрднрдЧ рдЗрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:



 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}} 

рдЗрд╕ рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдмрд╛рддреЗрдВ:


  1. __setattr__ рдХрд╛ __getattribute__ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдордХрдХреНрд╖ рдирд╣реАрдВ рд╣реИ (рдпрд╛рдиреА, рдЬрд╛рджреВ __setattribute__ рд╡рд┐рдзрд┐ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ)ред
  2. __setattr__ рдХреЛ __init__ рдХреЗ рдЕрдВрджрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рд╣рдо рд╕реНрд╡рдпрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реИрдВ ред__ рддрд╛рдирд╛рд╢рд╛рд╣реА __ ['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 .__ рддрд╛рдирд╛рд╢рд╛рд╣реА рдореЗрдВ рдХреНрдпрд╛ рд╣реИ?


 >>> f.__dict__ __getattribute__ was called {} 

__Dict__ рдореЗрдВ рдХреЛрдИ рдмрд╛рд░ рдХреБрдВрдЬреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди __getattr__ рдХреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред WAT?


рдмрд╛рд░ рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рд╕реНрд╡рдпрдВ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рд▓реЗрддреА рд╣реИ, рдХреЗрд╡рд▓ рдпрд╣ рд╡рд┐рдзрд┐ рдХрдХреНрд╖рд╛ рдореЗрдВ рд╣реИ, рди рдХрд┐ рдХрдХреНрд╖рд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВред рдФрд░ рдпрд╣ рджреЗрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ:


 >>> 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) -> рдорд╛рди


descr .__ рд╕реЗрдЯ __ (рд╕реНрд╡рдпрдВ, obj, рдореВрд▓реНрдп) -> рдХреЛрдИ рдирд╣реАрдВ


descr .__ delete __ (self, obj) -> рдХреЛрдИ рдирд╣реАрдВ



рдкреВрд░реЗ рдмрд┐рдВрджреБ рдпрд╣рд╛рдБ рд╣реИред рдЗрди рддреАрди рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЛ рднреА рд▓рд╛рдЧреВ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдмрди рдЬрд╛рдП рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓ рд╕рдХреЗред



рдпрджрд┐ рдХреЛрдИ рд╡рд╕реНрддреБ __get __ () рдФрд░ __set __ () рджреЛрдиреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рддреА рд╣реИ, рддреЛ рдЗрд╕реЗ рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░реНрд╕ рдЬреЛ рдХреЗрд╡рд▓ __get __ () рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдЧреИрд░-рдбреЗрдЯрд╛ рд╡рд┐рд╡рд░рдгрдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред



рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛрддреЗ рд╣реИрдВ рдХрд┐ рд╡рд╕реНрддреБ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╢рдмреНрджрдХреЛрд╢ рдХреЗ рддрддреНрд╡ рдХреИрд╕реЗ рд▓рд┐рдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдпрджрд┐ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рд╕рдорд╛рди рдирд╛рдо рд╡рд╛рд▓реА рдХреБрдВрдЬреА рд╣реИ, рддреЛ рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдкреВрд░реНрд╡рддрд╛ рд▓реЗрддрд╛ рд╣реИ (рдпрд╛рдиреА, __set __ () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдпрджрд┐ рдбрд┐рдХреНрд╢рдирд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рдмрд┐рдирд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рд╕рдорд╛рди рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рдХреБрдВрдЬреА рд╣реИ, рддреЛ рдбрд┐рдХреНрд╢рдирд░реА рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╣реИ (рдпрд╛рдиреА, рд╢рдмреНрджрдХреЛрд╢ рддрддреНрд╡ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рд╣реИ)ред



рд░реАрдб-рдУрдирд▓реА рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, __get __ () рдФрд░ __set __ () , рдЬрд╣рд╛рдВ __set __ () рдПрдЯреНрд░рд┐рдмреНрдпреВрдЯ рдПрд░реЛ рдХрд╣рддреЗ рд╣реИрдВ , рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВред рдбреЗрдЯрд╛ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ __set __ () рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред


рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрджрд┐ рдЖрдкрдиреЗ рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рддрд░реАрдХрд╛ __get__ , __set__ рдпрд╛ __delete__ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЖрдкрдиреЗ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рд╕рдВрдкрддреНрддрд┐ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд░рддрд╛ рд╣реИ: рдпрд╣ рдПрдХ рд░реАрдб-рдУрдирд▓реА рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдШреЛрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ __getattribute__ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред


рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдВрддрд┐рдо рдкрд░рд┐рд╡рд░реНрддрди:


foo.bar foo .__ getattribute __ ('рдмрд╛рд░') рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдЬреЛ рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдЗрд╕ рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:



 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 рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХрд╛ рд╣рдорд╛рд░рд╛ рдЕрдВрддрд┐рдо рдкреНрд░рдпрд╛рд╕ рдЖрдо рддреМрд░ рдкрд░ рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рд╣рдореЗрд╢рд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рдЫреЛрдЯреЗ рд╡рд┐рд╡рд░рдг рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдХреИрд╕реЗ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдХрд╛рдо рдХрд░рддреА рд╣реИрдВ, рдореИрдВ рдЙрд╕ рднрд╛рд╖рд╛ рдХреА рд╕реБрдВрджрд░рддрд╛ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛ рдЬреЛ рдЖрдкрдХреЛ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рддреА рд╣реИред рдЖрдЬ рдЬреНрдЮрд╛рди рдХрд╛ рдХреБрдЫ рдХрд░реНрдЬ рдЪреБрдХрд╛ рджреЛред

Source: https://habr.com/ru/post/hi479824/


All Articles