How can I copy a python class property? -
in attempt discover boundaries of python language i'm exploring whether possible go further information hiding convention of using leading underscore denote 'private' implementation details.
i have managed achieve additional level of privacy of fields , methods using code such copy 'public' stuff locally defined class:
from __future__ import print_function class dog(object): def __init__(self): class guts(object): def __init__(self): self._dog_sound = "woof" self._repeat = 1 def _make_sound(self): _ in range(self._repeat): print(self._dog_sound) def get_repeat(self): return self._repeat def set_repeat(self, value): self._repeat = value @property def repeat(self): return self._repeat @repeat.setter def repeat(self, value): self._repeat = value def speak(self): self._make_sound() guts = guts() # make public methods self.speak = guts.speak self.set_repeat = guts.set_repeat self.get_repeat = guts.get_repeat dog = dog() print("speak once:") dog.speak() print("speak twice:") dog.set_repeat(2) dog.speak() however, i'm struggling find way same property setter , getter.
i want able write code this:
print("speak thrice:") dog.repeat = 3 dog.speak() and print 'woof' 3 times.
i've tried of following in dog.__init__, none of blow up, neither seem have effect:
dog.repeat = guts.repeat self.repeat = guts.repeat dog.repeat = guts.repeat self.repeat = guts.repeat self.repeat = property(guts.repeat.getter, guts.repeat.setter) self.repeat = property(guts.repeat.fget, guts.repeat.fset)
descriptors work when defined on class, not instance. see this previous question , this one , the documentation abarnert pointed to. key statement is:
for objects, machinery in
object.__getattribute__()transformsb.xtype(b).__dict__['x'].__get__(b, type(b)).
note reference type(b). there 1 property object whole class, , instance information passed in @ access time.
that means can't have property on individual dog instance deals particular dog's guts. have define property on dog class, , have access guts of individual dog via self. except can't setup, because you're not storing reference dog's guts on self, because you're trying hide guts.
the bottom line can't proxy attribute access underlying "guts" object without storing reference object on "outward-facing" object. , if store such reference, people can use modify guts in "unauthorized" way.
also, sad say, existing example doesn't protect guts. can this:
>>> d = dog() >>> d.speak.__self__._repeat = 3 >>> d.speak() woof woof woof even though try hide guts exposing public methods of guts, public methods contain reference actual guts object, allowing sneak in , modify guts directly, bypassing information-hiding scheme. why it's futile try enforce information-hiding in python: core parts of language methods expose lot of stuff, , can't plug leaks.
Comments
Post a Comment