If you really need to use the ID this way, use parameters:
class Parent(object):
def __init__(self, id):
self.id = id
class Child1(Parent):
_id_counter = count(0)
def __init__(self):
Parent.__init__(self, 100 + self._id_counter.next())
print 'Child1:', self.id
etc.
This assumes you won't be constructing instances of Parent directly, but that looks reasonable with your example code.
If you really need to use the ID this way, use parameters:
class Parent(object):
def __init__(self, id):
self.id = id
class Child1(Parent):
_id_counter = count(0)
def __init__(self):
Parent.__init__(self, 100 + self._id_counter.next())
print 'Child1:', self.id
etc.
This assumes you won't be constructing instances of Parent directly, but that looks reasonable with your example code.
If you don't want to violate the DRY principle like falsetru suggests, you'll need to use metaclasses. I was thinking of writing something up, but there's already a good long description of metaclasses on SO, so check it out.
Metaclasses, in short, let you control subclass creation.
Basically, what you need to do is, upon the creation of a subclass of Parent, add the _id member to the newly-created subclass.
Cannot override class variable -- using `Final` and `ClassVar`
Changing Parent attributes through child class
Confused about class variables, also with inheritance
oop - Overriding class variables in python - Stack Overflow
How can I change the attributes of my parent class trough the child class?
class Parent:
def __init__(self):
self.name = "this the parent"
class Child(Parent):
def __init__(self):
pass
def change_name(self):
Parent.name = "text changed"
thank you in advance
I'm finding class variables super confusing. I thought they were just like static variables in C++ (which instances can't own), but it seems they have quite different behavior.
Basic Class variable behavior - is this correct?
class Foo: x: int
-
if you set
Foo.x, it overrides the value of.xfor all instances of Foo, but -
if you set
.xon an instance ofFoo, it only changes.xon that instance.
edit: actually this can't be the full story, because sometimes changing Foo.x doesn't change the instance's .x??
Class variables + inheritance, what is going on?
class Parent: x: int class Child(Parent): pass Parent.x = 1 print(Child.x) # = 1. ok so child inherits parent class variable Child.x = 2 print(Parent.x) # = 1. ok, so child cannot set parent class variable Parent.x = 3 print(Child.x) # = 2. hol' up, now child doesn't inherit from parent anymore?
Also, if multiple classes inherit from Parent, if I set Child1.x does it affect the other children? How are instances affected too?
Class variables without declaration works too...?
What's the point of defining these variables in the class body if you don't need to?
class Foo: pass Foo.x = 3
I feel like there's some kind of mental model for class variables I'm just not understanding. Is there any easy way to think about them? Also is there any other weird behavior I should know?
def showDefaultValue(cls, defl=default):
means that default gets evaluated when the function is defined, as usual in Python. So the definition looks like this then:
def showDefaultValue(cls, defl="default value in base"):
This value of defl is stored as a default argument on the function object and used when you call the method without arguments. You can look at the defaults of a function like print Descend.showDefaultValue.im_self.default to validate this.
If you want to get the default from the current class then you have get it from there:
@classmethod
def showDefaultValue(cls, defl=None):
if defl is None:
defl = cls.default
print "defl == %s" % (defl)
The class variable is being overwritten. Try
@classmethod
def showDefaultValue(cls):
print "defl == %s" % (cls.default,)
The reason your way doesn't work has more to do with the way Python treats default arguments to functions than with class attributes. The default value for defl is evaluated at the time Python defines the binding for showDefaultValue and this is done exactly once. When you call your method the default value used is what was evaluated at the time of definition.
In your case, defl was bound to the value of the default variable as it was during the execution of the class body form of Base. Regardless of how you call showDefaultValue later on (i.e., whether via Base or via Descend) that value remains fixed in all subsequent invocations of showDefaultValue.