èªã¿ãããã楜ããã䟿å©ãªæéãéããããã«ãèšèªã®ããã€ãã®åºæ¬çãªæŠå¿µãç¥ã£ãŠãããšããã§ãããã ç¹ã«ã åãšãªããžã§ã¯ããç解ããããšã¯éåžžã«åœ¹ç«ã¡ãäž¡æ¹ã®ãšã³ãã£ãã£ã®ããã€ãã®äŸãç¥ãããšãã§ããŸãã ãããå«ãããããã«ã€ããŠèªãããšãã§ããŸã ã
åéãããã€ã³ãã«å°éããåã«äœ¿çšããçšèªã«ã€ããŠå°ã説æããŸãã
- ãªããžã§ã¯ããšã¯ãPythonã®ä»»æã®ãšã³ãã£ãã£ïŒé¢æ°ãæ°å€ãæåå...ã€ãŸããããã§ãïŒã§ãã
- ã¯ã©ã¹ã¯ãã¿ã€ããã¿ã€ãã®ãªããžã§ã¯ãã§ãïŒã¿ã€ãã¯__class__å±æ§ã§ç¢ºèªã§ããŸãïŒã
- ã¯ã©ã¹A ã®ã€ã³ã¹ã¿ã³ã¹ã¯ ã __ class__å±æ§ã§ã¯ã©ã¹Aãžã®åç §ãæã€ãªããžã§ã¯ãã§ãã
ãããããèšäºã®äŸã¯ãã¹ãŠpython3ã§æžãããŠããŸã ïŒ ããã¯ééããªãèæ ®ãããã¹ãã§ãã
äžèšã®ã©ãããã次ã«äœãèµ·ããããç¥ããããšããããªãã®æ¬²æãåãããããšãã§ããªãã£ãããå§ããŸãããïŒ
__dict__
ãªããžã§ã¯ãã®å±æ§ã¯ãæ¡ä»¶ä»ãã§2ã€ã®ã°ã«ãŒãã«åããããšãã§ããŸããPythonã§å®çŸ©ããããã®ïŒ __class__ ã __bases__ãªã© ïŒãšãŠãŒã¶ãŒå®çŸ©ããããã®ã§ãã ãã®åé¡ã«ãã__dict__ã¯ããã·ã¹ãã ãïŒpythonã§å®çŸ©ïŒå±æ§ãæããŸãã ãã®ã¿ã¹ã¯ã¯ããŠãŒã¶ãŒå±æ§ãä¿åããããšã§ãã ããã¯èŸæžã§ãããããŒã¯ããããattribute_name ãvalueã attribute_valueã§ã ã
oãªããžã§ã¯ãã®å±æ§ãèŠã€ããããã«ãpythonã¯ä»¥äžãã¹ãã£ã³ããŸãïŒ
- ãªããžã§ã¯ãèªäœïŒ o .__ dict__ããã³ãã®ã·ã¹ãã å±æ§ïŒã
- ãªããžã§ã¯ãã¯ã©ã¹ïŒ o .__ class __.__ dict__ ïŒã ã·ã¹ãã å±æ§ã§ã¯ãªãã __ dict__ã¯ã©ã¹ã®ã¿ã
- ãªããžã§ã¯ãã¯ã©ã¹ã®ç¶æ¿å ã®ã¯ã©ã¹ïŒ o .__ class __.__ bases __.__ dict__ ïŒã
class StuffHolder: stuff = "class stuff" a = StuffHolder() b = StuffHolder() a.stuff # "class stuff" b.stuff # "class stuff" b.b_stuff = "b stuff" b.b_stuff # "b stuff" a.b_stuff # AttributeError
ãã®äŸã§ã¯ãäž¡æ¹ã®ã€ã³ã¹ã¿ã³ã¹ãç¶æ¿ãã1ã€ã®å±æ§stuffãæã€StuffHolderã¯ã©ã¹ã«ã€ããŠèª¬æããŸãã ãªããžã§ã¯ãbã« b_stuffå±æ§ãè¿œå ããŠãã aã«ã¯åœ±é¿ããŸããã
ãã¹ãŠã®ã¢ã¯ã¿ãŒã®__dict__ãèŠãŠã¿ãŸãããã
StuffHolder.__dict__ # {... 'stuff': 'class stuff' ...} a.__dict__ # {} b.__dict__ # {'b_stuff': 'b stuff'} a.__class__ # <class '__main__.StuffHolder'> b.__class__ # <class '__main__.StuffHolder'>
ïŒ __dict__ã®StuffHolderã¯ã©ã¹ã¯ãããŸããŸãªãžã£ã³ã¯ãæã€dict_proxyã¯ã©ã¹ã®ãªããžã§ã¯ããæ ŒçŽããŸããããŸã 泚æãæãå¿
èŠã¯ãããŸããïŒã
__dict__ã® aãbãstuffå±æ§ãæã¡ãŸãããããã§èŠã€ããããšãªããæ€çŽ¢ãšã³ãžã³ã¯__dict__ã¯ã©ã¹ïŒ StuffHolder ïŒã§ãããæ€çŽ¢ããã¯ã©ã¹ã§å²ãåœãŠãããå€ãèŠã€ããŠè¿ããŸãã ã¯ã©ã¹åç §ã¯ããªããžã§ã¯ãã®__class__å±æ§ã«æ ŒçŽãããŸãã
å±æ§ã®æ€çŽ¢ã¯å®è¡æã«è¡ããããããã€ã³ã¹ã¿ã³ã¹ãäœæããåŸã§ãã __ dict__ã¯ã©ã¹ã«å¯Ÿãããã¹ãŠã®å€æŽããããã«åæ ãããŸãã
a.new_stuff # AttributeError b.new_stuff # AttributeError StuffHolder.new_stuff = "new" StuffHolder.__dict__ # {... 'stuff': 'class stuff', 'new_stuff': 'new'...} a.new_stuff # "new" b.new_stuff # "new"
ã€ã³ã¹ã¿ã³ã¹å±æ§ã«å€ãå²ãåœãŠãå Žåã __dict__ã€ã³ã¹ã¿ã³ã¹ã®ã¿ãå€æŽãããŸã ãã€ãŸãã __dict__ã¯ã©ã¹ã®å€ã¯å€æŽãããŸããïŒã¯ã©ã¹å±æ§å€ãããŒã¿èšè¿°åã§ãªãå ŽåïŒïŒ
StuffHolder.__dict__ # {... 'stuff': 'class stuff' ...} c = StuffHolder() c.__dict__ # {} c.stuff = "more c stuff" c.__dict__ # {'stuff': 'more c stuff'} StuffHolder.__dict__ # {... 'stuff': 'class stuff' ...}
ã¯ã©ã¹ã®å±æ§åãšã€ã³ã¹ã¿ã³ã¹ãäžèŽããå Žåãã€ã³ã¿ããªã¿ã¯å€ãæ€çŽ¢ãããšãã«ã€ã³ã¹ã¿ã³ã¹ã®å€ãæ€çŽ¢ããŸãïŒã¯ã©ã¹å±æ§ã®å€ãããŒã¿èšè¿°åã§ãªãå ŽåïŒïŒ
StuffHolder.__dict__ # {... 'stuff': 'class stuff' ...} d = StuffHolder() d.stuff # "class stuff" d.stuff = "d stuff" d.stuff # "d stuff"
æŠã㊠ãããã__dict__ã«ã€ããŠèšããããšã®ãã¹ãŠã§ãã ããã¯ããŠãŒã¶ãŒå®çŸ©ã®å±æ§ã®ãªããžããªã§ãã å®è¡æã«æ€çŽ¢ãããæ€çŽ¢äžã«ãªããžã§ã¯ãã®__dict__ã¯ã©ã¹ãšåºæ¬ã¯ã©ã¹ãèæ ®ãããŸãã ãŸãããã®åäœããªãŒããŒã©ã€ãããæ¹æ³ãããã€ãããããšãç¥ã£ãŠããããšãéèŠã§ãã ãããã®1ã€ã¯ãå倧ã§åŒ·åãªèšè¿°åã§ãïŒ
èšè¿°å
å±æ§å€ãšããŠåçŽåã䜿çšãããšããããŸã§ã®ãšãããã¹ãŠãæ確ã«ãªããŸããã åãæ¡ä»¶äžã§é¢æ°ãã©ã®ããã«åäœããããèŠãŠã¿ãŸãããã
class FuncHolder: def func(self): pass fh = FuncHolder() FuncHolder.func # <function func at 0x8f806ac> FuncHolder.__dict__ # {...'func': <function func at 0x8f806ac>...} fh.func # <bound method FuncHolder.func of <__main__.FuncHolder object at 0x900f08c>>
WTFïŒïŒ ãã¶ã...å€åã ãé¡ãããŸãã ãã®å Žåã®æ©èœã¯ããã§ã«èŠããã®ãšã©ã®ããã«ç°ãªããŸããïŒ çãã¯ç°¡åã§ãã__get__ã¡ãœããã䜿çšããŸãã
FuncHolder.func.__class__.__get__ # <slot wrapper '__get__' of 'function' objects>
ãã®ã¡ãœããã¯ã fhã€ã³ã¹ã¿ã³ã¹ã®funcå±æ§ã®å€ãååŸããã¡ã«ããºã ããªãŒããŒã©ã€ããããã®ã¡ãœãããå®è£ ãããªããžã§ã¯ãã¯ã éããŒã¿èšè¿°åãšåŒã°ãã翻蚳äžå¯èœã§ãã
howtoããïŒ
èšè¿°åã¯ããããã³ã«èšè¿°åã®ã¡ãœããã«ãã£ãŠå±æ§ãä»ããŠåå®çŸ©ããããªããžã§ã¯ãã¢ã¯ã»ã¹ã§ã ã
descr .__ get __ïŒselfãobjãtype = NoneïŒ-> valueïŒå±æ§å€ã®åãåãæ¹æ³ããªãŒããŒã©ã€ãããŸãïŒ descr .__ set __ïŒselfãobjãvalueïŒ-> NoneïŒå±æ§ã«å€ãå²ãåœãŠãããæ¹æ³ããªãŒããŒã©ã€ãããŸãïŒ descr .__ delete __ïŒselfãobjïŒ-> NoneïŒå±æ§ã®åé€æ¹æ³ããªãŒããŒã©ã€ãããŸãïŒ
èšè¿°åã«ã¯2ã€ã®ã¿ã€ãããããŸãã
- ããŒã¿èšè¿°å-__get __ïŒïŒããã³__set __ïŒïŒã¡ãœãããå®è£ ãããªããžã§ã¯ã
- éããŒã¿èšè¿°åïŒããŒã¿èšè¿°åã§ã¯ãªãïŒïŒ -__get __ïŒïŒã¡ãœãããå®è£ ãããªããžã§ã¯ã
ããŒã¿èšè¿°å
ããŒã¿èšè¿°åã詳ããèŠãŠã¿ãŸãããã
class DataDesc: def __get__(self, obj, cls): print("Trying to access from {0} class {1}".format(obj, cls)) def __set__(self, obj, val): print("Trying to set {0} for {1}".format(val, obj)) def __delete__(self, obj): print("Trying to delete from {0}".format(obj)) class DataHolder: data = DataDesc() d = DataHolder() DataHolder.data # Trying to access from None class <class '__main__.DataHolder'> d.data # Trying to access from <__main__.DataHolder object at ...> class <class '__main__.DataHolder'> d.data = 1 # Trying to set 1 for <__main__.DataHolder object at ...> del(d.data) # Trying to delete from <__main__.DataHolder object at ...>
DataHolder.dataã®åŒã³åºãããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãªã__get__ Noneã¡ãœããã«æž¡ãããããšã«æ³šæããŠãã ããã
æ¥ä»èšè¿°åã__dict__ã€ã³ã¹ã¿ã³ã¹ã®ãšã³ããªãããæå©ã§ãããšããã¹ããŒãã¡ã³ããæ€èšŒããŠã¿ãŸãããã
d.__dict__["data"] = "override!" d.__dict__ # {'data': 'override!'} d.data # Trying to access from <__main__.DataHolder object at ...> class <class '__main__.DataHolder'>
ã€ãŸãã __ dict__ã€ã³ã¹ã¿ã³ã¹ã¯ã©ã¹ïŒãŸãã¯ãã®åºæ¬ã¯ã©ã¹ïŒã«åãååãšå€ïŒããŒã¿èšè¿°åïŒã®ãšã³ããªãããå Žåã __ dict__ã€ã³ã¹ã¿ã³ã¹ã®ãšã³ããªã¯ç¡èŠãããŸãã
ããäžã€ã®éèŠãªãã€ã³ãã ã¯ã©ã¹ãéããŠèšè¿°åã䜿çšããŠå±æ§ã®å€ãå€æŽãããšãèšè¿°åã¡ãœããã¯åŒã³åºããããã¯ã©ã¹ã®__dict__ã®å€ã¯éåžžã®å±æ§ã§ãããã®ããã«å€æŽãããŸãã
DataHolder.__dict__ # {...'data': <__main__.DataDesc object at ...>...} DataHolder.data = "kick descriptor out" DataHolder.__dict__ # {...'data': 'kick descriptor out'...} DataHolder.data # "kick descriptor out"
ããŒã¿èšè¿°åãªã
éããŒã¿èšè¿°åã®äŸïŒ
class NonDataDesc: def __get__(self, obj, cls): print("Trying to access from {0} class {1}".format(obj, cls)) class NonDataHolder: non_data = NonDataDesc() n = NonDataHolder() NonDataHolder.non_data # Trying to access from None class <class '__main__.NonDataHolder'> n.non_data # Trying to access from <__main__.NonDataHolder object at ...> class <class '__main__.NonDataHolder'> n.non_data = 1 n.non_data # 1 n.__dict__ # {'non_data': 1}
圌ã®æ¯ãèãã¯ãããŒã¿èšè¿°åãããããšãšã¯å°ãç°ãªããŸãã non_dataå±æ§ã«å€ãå²ãåœãŠãããšãããšã __ dict__ã€ã³ã¹ã¿ã³ã¹ã«æžã蟌ãŸããããã __ dict__ã¯ã©ã¹ã«æ ŒçŽãããŠãããã³ãã«ãé衚瀺ã«ãªããŸããã
䜿çšäŸ
èšè¿°åã¯ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã®å±æ§ãžã®ã¢ã¯ã»ã¹ãå¶åŸ¡ã§ãã匷åãªããŒã«ã§ãã ãããã®äœ¿çšã®äžäŸã¯é¢æ°ã§ã;ã€ã³ã¹ã¿ã³ã¹ãéããŠåŒã³åºããããšããããã¯ã¡ãœããã«ãªããŸãïŒäžèšã®äŸãåç §ïŒã èšè¿°åã䜿çšãããã1ã€ã®äžè¬çãªæ¹æ³ã¯ã ããããã£ãäœæããããšã§ãã ããããã£ãšã¯ããªããžã§ã¯ãã®ç¶æ ãç¹åŸŽä»ããç¹å®ã®å€ãæå³ãããã®ã¢ã¯ã»ã¹ã¯ç¹å¥ãªã¡ãœããïŒã²ãã¿ãŒãã»ãã¿ãŒïŒã䜿çšããŠå¶åŸ¡ãããŸãã èšè¿°åã䜿çšããŠããããã£ãäœæããã®ã¯ç°¡åã§ãã
class Descriptor: def __get__(self, obj, type): print("getter used") def __set__(self, obj, val): print("setter used") def __delete__(self, obj): print("deleter used") class MyClass: prop = Descriptor()
ãŸãã¯ãçµã¿èŸŒã¿ã¯ã©ã¹ããããã£ã䜿çšã§ããŸããããã¯ããŒã¿èšè¿°åã§ãã äžèšã®ã³ãŒãã¯æ¬¡ã®ããã«æžãæããããšãã§ããŸãã
class MyClass: def _getter(self): print("getter used") def _setter(self, val): print("setter used") def _deleter(self): print("deleter used") prop = property(_getter, _setter, _deleter, "doc string")
ã©ã¡ãã®å Žåã§ããåãåäœãåŸãããŸãã
m = MyClass() m.prop # getter used m.prop = 1 # setter used del(m.prop) # deleter used
ããããã£ã¯åžžã«ããŒã¿èšè¿°åã§ããããšãç¥ã£ãŠããããšãéèŠã§ãã ã³ã³ã¹ãã©ã¯ã¿ãŒïŒgetterãsetterããŸãã¯deliterïŒã«é¢æ°ãæž¡ããªãå Žåãå±æ§ã«å¯ŸããŠå¯Ÿå¿ããã¢ã¯ã·ã§ã³ãå®è¡ããããšãããšã AttributeErrorãã¹ããŒãããŸãã
class MySecondClass: prop = property() m2 = MySecondClass() m2.prop # AttributeError: unreadable attribute m2.prop = 1 # AttributeError: can't set attribute del(m2) # AttributeError: can't delete attribute
çµã¿èŸŒã¿èšè¿°åã«ã¯æ¬¡ã®ãã®ãå«ãŸããŸãã
- staticmethod-ã¯ã©ã¹å€ã®é¢æ°ãšåãã§ãã€ã³ã¹ã¿ã³ã¹ã¯æåã®åŒæ°ãšããŠæž¡ãããŸãã ã
- classmethod-ã¯ã©ã¹ã¡ãœãããšåããã€ã³ã¹ã¿ã³ã¹ã¯ã©ã¹ã®ã¿ãæåã®åŒæ°ãšããŠæž¡ãããŸãã
class StaticAndClassMethodHolder: def _method(*args): print("_method called with ", args) static = staticmethod(_method) cls = classmethod(_method) s = StaticAndClassMethodHolder() s._method() # _method called with (<__main__.StaticAndClassMethodHolder object at ...>,) s.static() # _method called with () s.cls() # _method called with (<class '__main__.StaticAndClassMethodHolder'>,)
__getattr __ïŒïŒã__ setattr __ïŒïŒã__ delattr __ïŒïŒããã³__getattribute __ïŒïŒ
ãªããžã§ã¯ãã®åäœãå±æ§ãšããŠæ±ºå®ããå Žåã¯ãèšè¿°åïŒããšãã°ã property ïŒã䜿çšããå¿ èŠããããŸãã ãªããžã§ã¯ãã®ãã¡ããªïŒ é¢æ°ãªã© ïŒã«ã€ããŠãåæ§ã§ãã å±æ§ãžã®ã¢ã¯ã»ã¹ã«åœ±é¿ãäžããå¥ã®æ¹æ³ã¯ã __ getattr __ïŒïŒ ã __setattr __ïŒïŒã__delattr __ïŒïŒãããã³__getattribute __ïŒïŒã¡ãœããã䜿çšããããšã§ãã èšè¿°åãšã¯ç°ãªãã å±æ§ãå«ããªããžã§ã¯ãã«å¯ŸããŠå®çŸ©ããå¿ èŠãããããã®ãªããžã§ã¯ãã®å±æ§ã«ã¢ã¯ã»ã¹ãããšãã«åŒã³åºãããŸãã
èŠæ±ãããå±æ§ãéåžžã®ã¡ã«ããºã ïŒ __dict__ã€ã³ã¹ã¿ã³ã¹ãã¯ã©ã¹ãªã©ïŒã§èŠã€ãããªãå Žåã __ getattr __ïŒselfãnameïŒãåŒã³åºãããŸãã
class SmartyPants: def __getattr__(self, attr): print("Yep, I know", attr) tellme = "It's a secret" smarty = SmartyPants() smarty.name = "Smartinius Smart" smarty.quicksort # Yep, I know quicksort smarty.python # Yep, I know python smarty.tellme # "It's a secret" smarty.name # "Smartinius Smart"
å±æ§å€ãååŸããããšãããšã__ getattribute __ïŒselfãnameïŒãåŒã³åºãããŸãã ãã®ã¡ãœããããªãŒããŒã©ã€ããããå Žåãæšæºã®å±æ§å€æ€çŽ¢ã¡ã«ããºã ã¯æå¹ã«ãªããŸããã çµã¿èŸŒã¿é¢æ°ãä»ããç¹å¥ãªã¡ãœããïŒ __len __ïŒïŒ ã __str __ïŒïŒãªã©ïŒã®åŒã³åºãããŸãã¯èšèªæ§æãä»ããæé»çãªåŒã³åºãã¯ã __getattribute __ïŒïŒããã€ãã¹ããããšã«æ³šæããŠãã ããã
class Optimist: attr = "class attribute" def __getattribute__(self, name): print("{0} is great!".format(name)) def __len__(self): print("__len__ is special") return 0 o = Optimist() o.instance_attr = "instance" o.attr # attr is great! o.dark_beer # dark_beer is great! o.instance_attr # instance_attr is great! o.__len__ # __len__ is great! len(o) # __len__ is special\n 0
ã€ã³ã¹ã¿ã³ã¹å±æ§ã®å€ãèšå®ããããšãããšã__ setattr __ïŒselfãnameãvalueïŒãåŒã³åºãããŸãã __getattribute __ïŒïŒãšåæ§ã«ããã®ã¡ãœããããªãŒããŒã©ã€ããããå Žåãæšæºå€èšå®ã¡ã«ããºã ã¯äœ¿çšãããŸããã
class NoSetters: attr = "class attribute" def __setattr__(self, name, val): print("not setting {0}={1}".format(name,val)) no_setters = NoSetters() no_setters.a = 1 # not setting a=1 no_setters.attr = 1 # not setting attr=1 no_setters.__dict__ # {} no_setters.attr # "class attribute" no_setters.a # AttributeError
__delattr __ïŒselfãnameïŒ -__setattr __ïŒïŒã«äŒŒãŠããŸãããå±æ§ãåé€ãããšãã«äœ¿çšãããŸãã
__getattribute __ïŒïŒ ã __setattr __ïŒïŒãããã³__delattr __ïŒïŒããªãŒããŒã©ã€ãããå Žåãå±æ§ã«ã¢ã¯ã»ã¹ããæšæºçãªæ¹æ³ã¯ãªããžã§ã¯ããä»ããŠåŒã³åºãããšãã§ããããšã«æ³šæããŠãã ããã
class GentleGuy: def __getattribute__(self, name): if name.endswith("_please"): return object.__getattribute__(self, name.replace("_please", "")) raise AttributeError("And the magic word!?") gentle = GentleGuy() gentle.coffee = "some coffee" gentle.coffee # AttributeError gentle.coffee_please # "some coffee"
å¡©
ãããã£ãŠãPythonã®aã®ã€ã³ã¹ã¿ã³ã¹ã®attrnameå±æ§å€ãååŸããã«ã¯ïŒ
- .__ class __.__ getattribute __ïŒïŒã¡ãœãããå®çŸ©ãããŠããå Žåããã®ã¡ãœãããåŒã³åºãããåä¿¡ããå€ãè¿ãããŸãã
- attrnameã__class__ã__doc__ãªã©ã®ç¹å¥ãªïŒpythonã§å®çŸ©ãããïŒå±æ§ã§ããå Žåããã®å€ãè¿ãããŸãã
- .__ class __.__ dict__ã§attrnameãæã€ãšã³ããªããã§ãã¯ããŸã ã ååšããå€ãããŒã¿èšè¿°åã§ããå Žåã èšè¿°åã®__get __ïŒïŒã¡ãœãããåŒã³åºããçµæãè¿ãããŸãã ãã¹ãŠã®åºæ¬ã¯ã©ã¹ããã§ãã¯ãããŸãã
- attrnameãšããååã®ãšã³ããªã.__ dict__ã«ååšããå Žåããã®ãšã³ããªã®å€ãè¿ãããŸãã aãã¯ã©ã¹ã®å Žåãå±æ§ã¯ãã®åºæ¬ã¯ã©ã¹éã§ãæ€çŽ¢ãããããŒã¿èšè¿°åãããå ŽåããŸãã¯__dict__ã« ããå Žåãèšè¿°åã®__get __ïŒïŒã®çµæãè¿ãããŸãã
- .__ class __.__ dict__ããã§ãã¯ãã attrnameãå«ããšã³ããªããããããããããŒã¿èšè¿°åãã§ããå Žåãçµæã¯èšè¿°åã®__get __ïŒïŒã«ãªããŸããã¬ã³ãŒããååšããèšè¿°åããªãå Žåãã¬ã³ãŒãã®å€ãè¿ãããŸãã åºæ¬ã¯ã©ã¹ãæ€çŽ¢ãããŸãã
- .__ class __.__ getattr __ïŒïŒã¡ãœãããååšããå ŽåããããåŒã³åºããããã®çµæãè¿ãããŸãã ãã®ãããªã¡ãœããããªãå Žåã AttributeErrorãã¹ããŒãããŸãã
ã€ã³ã¹ã¿ã³ã¹aã® attrnameå±æ§ã®å€ãèšå®ããã«ã¯ ïŒ
- .__ class __.__ setattr __ïŒïŒã¡ãœãããååšããå ŽåãåŒã³åºãããŸãã
- .__ class __.__ dict__ããã§ãã¯ããŸããattrnameãæã€ãšã³ããªãããããããããŒã¿èšè¿°åã§ããå Žåãèšè¿°åã®__set __ïŒïŒã¡ãœãããåŒã³åºãããŸãã åºæ¬ã¯ã©ã¹ããã§ãã¯ãããŸãã
- attrnameããŒãæã€å€ãšã³ããªã.__ dict__ã«è¿œå ãããŸã
__slots__
Guidoãæ°ããã¹ã¿ã€ã«ã®ã¯ã©ã¹ãã©ã®ããã«çºæããããã«ã€ããŠã®pythonã¹ããŒãªãŒã§æžããŠããããã«ïŒ
...ã¯ã©ã¹ã·ã¹ãã ã®å€æŽãããã©ãŒãã³ã¹ã«æªåœ±é¿ãäžããã®ã§ã¯ãªãããšå¿é ããŸããã ç¹ã«ãããŒã¿èšè¿°åãæ£ããæ©èœããããã«ããªããžã§ã¯ãã®å±æ§ã䜿çšãããã¹ãŠã®æäœã¯ããã®å±æ§ãããŒã¿èšè¿°åã§ãããšããäºå®ã«ã€ããŠ__dict__ã¯ã©ã¹ããã§ãã¯ããããšããå§ãŸããŸãã...
ãŠãŒã¶ãŒãããã©ãŒãã³ã¹ã®äœäžã«å€±æããå Žåãæãããã®ããPythonéçºè ã¯__slots__ãæãã€ããŸãã ã
__slots__ã®ååšã¯ããªããžã§ã¯ãã®å¯èœãªå±æ§åãããã«ç€ºãããŠãããã®ã«å¶éããŸãã ãŸãããã¹ãŠã®å±æ§åãäºåã«ããã£ãŠããããã __ dict__ã€ã³ã¹ã¿ã³ã¹ãäœæããå¿ èŠããªããªããŸãã
class Slotter: __slots__ = ["a", "b"] s = Slotter() s.__dict__ # AttributeError sc = 1 # AttributeError sa = 1 sa # 1 sb = 1 sb # 1 dir(s) # [ ... 'a', 'b' ... ]
ã®ãã®ææã¯å®çŸããªãã£ãããšãå€æããŸããããæããã«ãªããŸã§ã«ã¯ãã§ã«æé ãã§ããã ããã«ã __ slots__ã䜿çšãããšãç¹ã«å€ãã®å°ããªãªããžã§ã¯ããäœæãããšãã«äœ¿çšãããã¡ã¢ãªã®éãæžããããšã«ãããå®éã«ããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
ãããã«
Pythonã®å±æ§ãžã®ã¢ã¯ã»ã¹ã¯ãéåžžã«å€ãã®æ¹æ³ã§å¶åŸ¡ã§ããŸãã ãããã¯ããããç¬èªã®åé¡ã解決ããäžç·ã«ãªããžã§ã¯ãã䜿çšããã»ãšãã©ãã¹ãŠã®èããããã·ããªãªã«é©ããŠããŸãã ãããã®ã¡ã«ããºã ã¯ãè€æ°ã®ç¶æ¿ãã¡ã¿ã¯ã©ã¹ãããã³ãã®ä»ã®å©ç¹ãšãšãã«ãèšèªã®æè»æ§ã®åºç€ã§ãã å±æ§ãåŠçããããã®ãã®å€ãã®ãªãã·ã§ã³ãç解ããç解ãããããŠæãéèŠãªããšã«ã¯åãå ¥ããã®ã«æéãããããŸããã äžèŠãå°ãåé·ã§ãç¹ã«è«ççã§ã¯ãªãããã«èŠããŸããããããæ¥åžžã®ããã°ã©ãã³ã°ã§ã¯ã»ãšãã©åœ¹ã«ç«ããªãããšãèãããšããã®ãããªåŒ·åãªããŒã«ãæŠåšã«æã€ããšã¯çŽ æŽãããããšã§ãã
ãã®èšäºã§ãããªãã®æãéãæããããªãã£ãããã€ãã®ãã€ã³ããæ確ã«ããŠã»ãããšæããŸãã ãããŠä»ãããªãã®ç®ã«ç«ãã€ããPointã«èªä¿¡ãæã£ãŠããã®ã§ãã³ãŒãèŠä»¶ã®å€æŽã«å¯ŸããŠãæãã¯ãªãŒã³ã§èªã¿ããããèæ§ã®ããèšå€§ãªéãæžããŸãïŒ ãŸãããŸãã¯ã³ã¡ã³ãã
ãæéãããã ãããããšãããããŸãã
åç §è³æ
- ã·ã£ã©ããã£ãã¥ã«ããã£ã Pythonã®å±æ§ãšã¡ãœãã
- ã°ã€ããŽã¡ã³ãããµã ã æ°ããã¹ã¿ã€ã«ã®ã¯ã©ã¹ã®å éšã¹ããŒãªãŒ
- Pythonããã¥ã¡ã³ã