рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░ред
рдпрд╣ рд╕рд╛рдЗрдЯ
pyobject.ru рд╕реЗ рдкрд╛рдпрдерди рдкрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЬрд╡рд╛рдмреЛрдВ рдХреА рдПрдХ рдирд┐рд░рдВрддрд░рддрд╛ рд╣реИред
рдЕрд╕реНрд╡реАрдХрд░рдг :
рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдЙрддреНрддрд░реЛрдВ рдХреЛ рд╕рдмрд╕реЗ рд╕рд╣реА рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЕрдзрд┐рдХ рдЕрдиреБрднрд╡реА рд▓реЛрдЧ рддреНрд░реБрдЯрд┐рдпреЛрдВ, рдЕрд╢реБрджреНрдзрд┐рдпреЛрдВ рдФрд░ рдмреБрд░реЗ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВрдЧреЗред рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╡реЗ рдЖрдкрдХреЛ рдЕрдЧреНрд░рд┐рдо рдзрдиреНрдпрд╡рд╛рдж рджреЗрддреЗ рд╣реИрдВред
рдХрдХреНрд╖рд╛рдПрдВ
1. рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдЕрд╡рд▓реЛрдХрди рдХрд░реЗрдВ, рдЬреЛ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░рд┐рдпреЛрдВ рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛:
рдПрдХред рдЬрдм ** kwargs рд╕рдВрдЪрд╛рд░рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдорд╛рди рджрд░реНрдЬ рдХрд░реЗрдВ
рдЦред рд╕рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдкреНрд░рд┐рдВрдЯ рдкреНрд░рджрд░реНрд╢рди рдХрд░реЗрдВ
рд╡рд┐рд╢реЗрд╖рддрд╛ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдкрд░, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реЛрддрд╛ рд╣реИ (рдпрд╣рд╛рдБ рд╡рд╣ рдЭреВрда рдмреЛрд▓ рд╕рдХрддрд╛ рд╣реИ):
1. рдЗрд╕рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рд╡рд╕реНрддреБ рдХреЛ рд╕реНрд╡рдпрдВ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХрд╕реНрдЯрдо рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ __dict__ рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИрдВред
2. рд╡рд╕реНрддреБ рдХреЗ рдкреНрд░рдХрд╛рд░ __dict__ рдХреЛ рд╡рд╕реНрддреБ рдХреЗ __class __.__ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ
3. рдорд╛рддрд╛-рдкрд┐рддрд╛ рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рд╣реИрдВ
4. рдирдИ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП __getattribute__ рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЧрдИ рд╣реИ
5. __getattr__ рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЧрдИ рд╣реИ
рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ __dict__ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдЬреЛ рдХрд┐ __init__ рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред
__Str__ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА "рд╕реВрдЪрдирд╛рддреНрдордХ рдкреНрд░рд╕реНрддреБрддрд┐" рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
class Observable(object): """ Base class for attributes from dict. >>> class X(Observable): ... pass >>> x = X(foo=1, bar="Test", _barr='hidden', baz=(5, 6)) >>> print x X(bar=Test, foo=1, baz=(5, 6)) >>> print x.foo 1 >>> print x.bar Test >>> print x._barr hidden >>> print x.baz (5, 6) """ def __init__(self, **kwargs): self.__dict__.update(kwargs) def __str__(self): return '%s(%s)' % (self.__class__.__name__,\ (', '.join('%s=%s' % (key, val) for (key, val)\ in self.__dict__.iteritems() if not key.startswith('_'))))
2. рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд▓рд┐рдЦреЗрдВ рдЬреЛ рд╕рднреА рдмрд╛рд╣рд░реА рд╕рдВрдХреЗрддреЛрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реЛ, рд▓реЗрдХрд┐рди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрдВрдЬреА рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВред
рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд╕рднреА рдмрд╛рд╣рд░реА рд╕рдВрдХреЗрддреЛрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рдЗрд╕ рд╢рдмреНрджрдХреЛрд╢ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓реЗрдВрдЧреЗред рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд┐ рдЪрд╛рдмрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╡рд░реНрдЧ рдореЗрдВ рд╣рдо __getattr__ рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рд╡рд┐рд╢реЗрд╖рддрд╛ рд╡рд╕реНрддреБ, рдЙрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓рддреА рд╣реИред
class DictAttr(dict): """ Base class for JS-style dict. >>> x = DictAttr([('one', 1), ('two', 2), ('three', 3)]) >>> print x {'three': 3, 'two': 2, 'one': 1} >>> print x['three'] 3 >>> print x.get('two') 2 >>> print x.one 1 >>> print x.test Traceback (most recent call last): ... AttributeError """ def __getattr__(self, name): try: return self[name] except KeyError: raise AttributeError
3. рдмрд┐рдВрджреБ 2 рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рд╕рд╛рде: рдореВрд▓ рд╡рд░реНрдЧ XDictAttr рд▓рд┐рдЦреЗрдВ рддрд╛рдХрд┐ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА get_KEY рд╡рд┐рдзрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛред
рдореИрдВрдиреЗ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рдордп рдмрд┐рддрд╛рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЗрд╕реЗ рдлреИрд╢рдиреЗрдмрд▓, рд╕реНрдЯрд╛рдЗрд▓рд┐рд╢, рдпреБрд╡рд╛ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ рдФрд░ рди рд╣реА рдмреИрд╕рд╛рдЦреАред рдЬреЛ рд╣реБрдЖ рд╡реЛ рдЖрдкрдХреЗ рдКрдкрд░ рд╣реИ
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
1. __getitem__ рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ [рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрд▓ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ]
рдЬрдм рд╣рдо рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдореВрд▓ __getemem__ рдкрд░ рдХреЙрд▓ рдХрд░рдХреЗ рд╢рдмреНрджрдХреЛрд╢ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдХреЗ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рддрддреНрд╡ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдерд╛, рддреЛ рд╣рдо __getattr__ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо get_KEY рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ
2. рдкреНрд░рд╛рдкреНрдд () рд╡рд┐рдзрд┐ рдорд╛рдирдХ рдкреНрд░рд╛рдкреНрдд () рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдЕрдзрд┐рднрд╛рд╡ рдХреЛ рдкрд╛рд░ рдХрд░ рдЬрд╛рддреА рд╣реИред рд╣рдо рдкрд╣рд▓реЗ __getattr__ рдФрд░ get_KEY рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдХреЗрд╡рд▓ рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдо рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд __getitem__ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ рдФрд░ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рддрд░реНрдХ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ред
3. __getattr__ рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ рдЕрдиреНрдп рд╕рднреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреИрд░реЗрдВрдЯ __getitem__ рдХреЛ рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдпрд╣рд╛рдВ, рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рдЧрдВрджрд╛ рд╣реИрдХ рдЦреЗрд▓ рдореЗрдВ рдЖрддрд╛ рд╣реИред рдореИрдВ рдЕрднреА рднреА рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддрд╛ рдХрд┐ рдХреИрд╕реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рдП, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ get_KEY рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рд╣реИ, рдЬреЛ __getattr__ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддреА рд╣реИред рдЦреИрд░, рдЖрдкрдХреЛ рдмрд╛рдд рд╕рдордЭ рдореЗрдВ рдЖ рдЧрдИред рдЕрдВрдд рдореЗрдВ, рдореЗрд░реЗ рдкрд╛рд╕ get_get_get_get_get_get_foo рдЬреИрд╕реА рд▓рд╛рдЗрди рдереАред
рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдиреБрдХрд╕рд╛рди рдпрд╣ рд╣реИ рдХрд┐ get_ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЧреБрдг рдПрдХ рдЧреБрдг рдХреЛ рдмрдврд╝рд╛рдПрдВрдЧреЗред рдпрд╣ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд▓рд┐рдП рдореИрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
class XDictAttr(dict): """ >>> class X(XDictAttr): ... def get_foo(self): ... return 5 ... def get_bar(self): ... return 12 ... def get_get_z(self): ... return 42 >>> x = X({'one': 1, 'two': 2, 'three': 3}) >>> x {'one': 1, 'three': 3, 'two': 2} >>> x['one'] 1 >>> x.three 3 >>> x.bar 12 >>> x['foo'] 5 >>> x.get('foo', 'missing') 5 >>> x.get('bzz', 'missing') 'missing' >>> x.get_bar() 12 >>> x.get_foz() Traceback (most recent call last): ... AttributeError >>> x.get_get_z() 42 >>> x.get('get_z') 42 >>> x.get_z Traceback (most recent call last): ... AttributeError """ def __getattr__(self, name): try: return super(XDictAttr, self).__getitem__(name) except KeyError: if not name.startswith('get_'): return getattr(self, 'get_%s' % name)() else: raise AttributeError def __getitem__(self, key): try: return super(XDictAttr, self).__getitem__(key) except KeyError: return getattr(self, 'get_%s' % key)() def get(self, key, default=None): try: return getattr(self, 'get_%s' % key)() except AttributeError: return super(XDictAttr, self).get(key, default)
4. рдПрдХ рд╡рд░реНрдЧ рд▓рд┐рдЦреЗрдВ рдЬреЛ рдЕрдкрдиреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ
рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВ рдкрд╛рдпрдерди рдореЗрдВ рдЬреНрдпрд╛рджрд╛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рд▓рд┐рдП рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕реЗрд╕ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдард╣рд░рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
>>> for i in Reg: ... print i <Reg instance at 0x98b6ecc> <Reg instance at 0x98b6fec> <Reg instance at 0x98ba02c>
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рддрд╛рддреНрдкрд░реНрдп рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдПрдХ рдЗрдЯреНрд░реЗрдЯрд░ рд▓реЗрддреЗ рд╣реИрдВ, рдПрдХ рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБ рдирд╣реАрдВред рдФрд░ рдЕрдЬрдЧрд░ рджреБрднрд╛рд╖рд┐рдпрд╛ рдПрдХ рд╕рдорд╛рди рддреНрд░реБрдЯрд┐ рдЬрдм рдореИрдВрдиреЗ __iter__ рдХреЛ рдПрдХ рд╡рд░реНрдЧрдорд┐рдереЛрдб рдпрд╛ рд╕реНрдЯреЗрдЯрдорд┐рдереЛрдб рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдереАред
рдЗрд╕рд▓рд┐рдП, рдореЗрд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
class RegBase(type): def __iter__(cls): return iter(cls._instances) class Reg(object): """ >>> x = Reg() >>> x # doctest: +ELLIPSIS <__main__.Reg object at 0x...> >>> y = Reg() >>> y # doctest: +ELLIPSIS <__main__.Reg object at 0x...> >>> z = Reg() >>> z # doctest: +ELLIPSIS <__main__.Reg object at 0x...> >>> for i in Reg: # doctest: +ELLIPSIS ... print i <__main__.Reg object at 0x...> <__main__.Reg object at 0x...> <__main__.Reg object at 0x...> """ __metaclass__ = RegBase _instances = [] def __init__(self): self._instances.append(self)
PS рд╣рд╛рдБ, рдФрд░ рд░реЗрдЧ рдЙрджрд╛рд╣рд░рдг рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ Reg рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИред рд╢рд╛рдпрдж рдореЗрд░рд╛ рдЬрд╛рдореНрдм рдпрд╣рд╛рдБ рд╣реИ?
рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕реЗрд╕ рдФрд░ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░реНрд╕
рд╕рдВрднрд╡рддрдГ рд╕рдмрд╕реЗ рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рдЦрдВрдб, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕реЗрд╕ рдХрд╛ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рдерд╛: "рдпрджрд┐ рдЖрдкрдХреЛ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЖрдкрдХреЛ рдореЗрдЯрд╛рдХреНрд▓рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред" рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред
рд╕рд╡рд╛рд▓:
рдореИрдВ рдкреНрд░рд▓реЗрдЦрди (рдбреЗрдЯрд╛ рдореЙрдбрд▓) рдХреЛ рдЙрджреНрдзреГрдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рд▓рд┐рдЦреВрдВрдЧрд╛: рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕реЗрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИрдмреЗ рдкрд░ рдЕрдЪреНрдЫреЗ рд▓реЗрдЦ рд╣реИрдВред
рдЗрдзрд░ рдФрд░
рдЙрдзрд░ ред рдЙрдирдХреЗ рд▓реЗрдЦрдХреЛрдВ рдХреЛ рдзрдиреНрдпрд╡рд╛рджред
рдХрд╛рд░реНрдп:
1. рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдЬреЛ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдареАрдХ рдХрд░реЗрдЧрд╛ред
рджреЛ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдПрдХ рд╡рд┐рд╡рд░рдгрдХ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдирдП рддрд░рд╣ рдХреЗ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЧреБрдг рд╣реИред
рд╡рд┐рд╡рд░рдгрдХрд░реНрддрд╛рдУрдВ рдкрд░ рдПрдХ рд▓реЗрдЦ
рдпрд╣рд╛рдБ рд╣реИред class Property(object): """ >>> class Image(object): ... height = Property(0) ... width = Property(0) ... path = Property('/tmp/') ... size = Property(0) >>> img = Image() >>> img.height = 340 >>> img.height 340 >>> img.path = '/tmp/x00.jpeg' >>> img.path '/tmp/x00.jpeg' >>> img.path = 320 Traceback (most recent call last): ... TypeError """ def __init__(self, value): self.__value = value self.__value_type = type(value) def __get__(self, obj, objtype=None): return self.__value def __set__(self, obj, value): if type(value) == self.__value_type: self.__value = value else: raise TypeError
2. рдмреЗрд╕ рдХреНрд▓рд╛рд╕ (рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдЬреЛ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рдХрд╛рд░ рдХреЛ рдареАрдХ рдХрд░реЗрдЧрд╛ред
рдпрд╣рд╛рдБ рдореБрдЭреЗ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдереА - рдореИрдВ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдмрд┐рд▓рдХреБрд▓ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рдерд╛ред рд▓реЗрдЦрдХ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдмрд╛рдж, рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдКрдВрдЪрд╛рдИ, рдкрде рд╡рд░реНрдЧ рд╣реИрдВред рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рдерд╛ рдХрд┐ рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕ рдХреЛ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЛ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдФрд░ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдХреЗрд╡рд▓ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рджреВрд╕рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред
рд╕рдВрдкрддреНрддрд┐ рд╡рд░реНрдЧ рдХрд╛рд░реНрдп 1 рдХреЗ рдЙрддреНрддрд░ рдХреЗ рд╕рдорд╛рди рд╣реИред
рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЙрд╕ рд╕рдВрдкрддреНрддрд┐ рдХреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕ рдХреЛ рдХреНрд▓рд╛рд╕ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред
рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЙрдиреНрд╣реЛрдВрдиреЗ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рдХреНрдпрд╛ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реИ рдпрд╛ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ред
class ImageMeta(type): def __new__(mcs, name, bases, dct): for key, val in dct.iteritems(): if not key.startswith('_') and not hasattr(val, '__call__'): dct[key] = Property(val) return type.__new__(mcs, name, bases, dct) class ImageBase(object): """ >>> class Image(ImageBase): ... height = 0 ... path = 'tmp' ... ... def foo(self): ... return 'bar' >>> img = Image() >>> img.height = 340 >>> img.height 340 >>> img.path = '/tmp/x00.jpeg' >>> img.path '/tmp/x00.jpeg' >>> img.path = 320 Traceback (most recent call last): ... TypeError >>> hasattr(img.foo '__call__') True """ __metaclass__ = ImageMeta
3. рдмреЗрд╕ рдХреНрд▓рд╛рд╕ (рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдФрд░ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдЬреЛ рдХреНрд▓рд╛рд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП SQL-рд╕реНрдХреАрдорд╛ (ANSI SQL) рдмрдирд╛рдПрдВрдЧреЗред
рдХреГрдкрдпрд╛ рдЗрд╕ рд╡рд┐рдзрд┐ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдХрд┐рдП рдЧрдП рдереЗ:
1. рдмреЗрд╕рд┐рдХ рдкреНрд░реЙрдкрд░реНрдЯреА рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдПрдХ рдХреНрд▓рд╛рд╕ рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд╕рд╛рде рдЬреЛ рдЖрдкрдХреЛ рдЙрд╕ рдХреНрд░рдо рдореЗрдВ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡реЗ рдмрдирд╛рдП рдЧрдП рдереЗред
2. рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ __str__ рдХреЗ рд╕рд╛рде рдЗрдВрдЯреЗрдЧрд░ рдФрд░ рд╕реНрдЯреНрд░рд░ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░, рдЬреЛ рдореЙрдбрд▓ рдХреЗ рдПрд╕рдХреНрдпреВрдПрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рдмрдирд╛рддреЗ рд╕рдордп рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
3. рдореЗрдЯрд╛рдХреНрд▓рд╛рд╕ рдЯреЗрдмрд▓рдореЗрдЯрд╛, рдЬреЛ рдореЙрдбрд▓ рдлрд╝реАрд▓реНрдб рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдореЙрдбрд▓ рдХрд╛ рдПрдХ SQL рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдмрдирд╛рддрд╛ рд╣реИред
4. рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рддрд╛рд▓рд┐рдХрд╛, рдЬреЛ рдПрдХ рд╡рд░реНрдЧ рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ рдЬреЛ рдореЙрдбрд▓ рдХреЗ рдПрд╕рдХреНрдпреВрдПрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддреА рд╣реИред
class Property(object): """ >>> class Image(object): ... size = Property(int) ... name = Property(basestring) >>> img = Image() >>> img.size = 0 >>> img.size 0 >>> img.name = '/tmp/img' >>> img.name '/tmp/img' >>> img.size = '~' Traceback (most recent call last): ... TypeError >>> img.name = ['/tmp/', 'img'] Traceback (most recent call last): ... TypeError >>> img.__class__.__dict__['size'].counter 0 >>> img.__class__.__dict__['name'].counter 1 """ counter = 0 def __init__(self, value_type): self.__value = None self.__value_type = value_type self.counter = Property.counter Property.counter += 1 def __get__(self, obj, objtype=None): return self.__value def __set__(self, obj, value): if isinstance(value, self.__value_type): self.__value = value else: raise TypeError class Integer(Property): def __init__(self): super(Integer, self).__init__(int) def __str__(self): return self.__class__.__name__.upper() class Str(Property): def __init__(self, size): super(Str, self).__init__(basestring) self.__size = size def __str__(self): return '{0}({1})'.format('varchar', self.__size).upper() class TableMeta(type): def __new__(mcs, name, bases, dct): fields = [(attr_name, val) for (attr_name, val) in dct.items()\ if isinstance(val, Property)] fields.sort(key=lambda x: x[1].counter) sql = ',\n'.join('\t{0} {1}'.format(attr_name, val)\ for (attr_name, val) in fields) dct['__sql'] = u'CREATE TABLE {0} (\n{1}\n)'.format(name, sql) return type.__new__(mcs, name, bases, dct) class Table(object): """ >>> class Image(Table): ... height = Integer() ... width = Integer() ... path = Str(128) >>> print Image.sql() # doctest: +NORMALIZE_WHITESPACE CREATE TABLE Image ( height INTEGER, width INTEGER, path VARCHAR(128) ) """ __metaclass__ = TableMeta @classmethod def sql(cls): return cls.__dict__['__sql']
рд╡рд╣ рд╕рдм рд╣реИред рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рдЖрд▓реЛрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред