Note that there are some explanatory texts on larger screens.

plurals
  1. POpython:class attribute/variable inheritance with polymorphism?
    primarykey
    data
    text
    <p>In my endeavours as a python-apprentice i got recently stuck at some odd (from my point of view) behaviour if i tried to work with class attributes. I'm not complaining, but would appreciate some helpful comments to shed some light on this issue.</p> <p>To reduce a complex matter into a more concise question i would formulate it like this:</p> <p>What is the "pythonic" way to ensure that a class-attribute behaves more like a static variable in an inheritance tree?</p> <p>It seems to me like a class-attribute behaves like a "copy on read" default value with polymorphic characteristics. As long as i do "read-only" operations it stays a "singleton", but as soon, as i access the class-attribute with an assignment through the derived class or instance it gets morphed into a new reference loosing the relation to the inherited base-reference.</p> <p>(It has sure potential for some interessting features, but you have to understand it to embrace it, so some insight is highly appreciated.)</p> <pre><code>class A(object): classvar = 'A' def setclassvar(self, value): A.classvar = value def __str__(self): return "%s id(%s) " %(A.classvar, hex(id(A.classvar))[2:-1].upper()) class A1(A): pass class B(object): classvar = 'B' def setclassvar(self, value): self.__class__.classvar = value def __str__(self): cvar = self.__class__.classvar return "%s id(%s) " %(cvar, hex(id(cvar))[2:-1].upper()) class B1(B): def setclassvar(self, value): self.__class__.classvar = value a, a1 = A(), A1() a1.setclassvar('a') print "new instance A: %s" %a print "new instance A1: %s" %a b, b1 = B(), B1() b1.setclassvar('bb') print "new instance B: %s" %b print "new instance B1: %s" %b1 a1.setclassvar('aa') print "new value a1: %s" %a print "new value a: %s" %a a1.classvar = 'aaa' print "direct access a1: %s id(%s)" %(a1.classvar, hex(id(a1.classvar))[2:-1].upper()) print "method access a1: %s" %a1 print "direct access a: %s" %a </code></pre> <p>produces the following:</p> <blockquote> <pre><code>new instance A: a id(B73468A0) new instance A1: a id(B73468A0) new instance B: B id(B73551C0) new instance B1: bb id(AD1BFC) new value a1: aa id(AD1BE6) new value a: aa id(AD1BE6) direct access a1: aaa id(A3A494) method access a1: aa id(AD1BE6) direct access a: aa id(AD1BE6) </code></pre> </blockquote> <p>So either the direct (assigning) access <code>object.classvar</code> or mediated through <code>self.__class__.classvar</code> are not the same as <code>BASECLASS.classvar</code>.</p> <p>Is this a scope issue or somethin totaly different. </p> <p>Looking forward to your answers and thanks in forward. :-)</p> <hr> <p>Edit: There was an answer for a very short time suggesting the use of class-descriptors like: <a href="https://stackoverflow.com/questions/5189699/how-can-i-make-a-class-property-in-python">How to make a class property?</a>.</p> <p>Unfortunatly that doesn't seem to work:</p> <pre><code>class Hotel(Bar): def __init__(self): Hotel.bar += 1 hotel = Hotel() assert hotel.bar == 51 assert hotel.bar == foo.bar </code></pre> <p>The 2nd assertion fails! hotel.bar doesn't reference the same object as <code>foo.bar</code> and <code>hotel.bar</code> references somethin other then Hotel.bar!</p> <hr> <p>2nd Edit: I'm quite aware that singletons are considered an "antipattern" and i didn't intend to use them (extensivly). Therefore i didn't mention them in the question-titel. Even so there are many solutions discussing and providing solutions with and about singletons, my question stays: Why can a class-variable detach it's reference so easily? Ruby behaves more the way it feels natural to me: <a href="http://snippets.dzone.com/posts/show/6649" rel="nofollow noreferrer">http://snippets.dzone.com/posts/show/6649</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload