In an inherited class, "embedded" classes is referenced?

  • Thread starter Christian Joergensen
  • Start date
C

Christian Joergensen

Hello

I stumpled upon this "feature" during my work tonight, and found it
a bit confusing:
.... class C:
.... foobar = 42
.... 60

When I inherit B from A, I would expect that A.C and B.C would be two
different classes? But apparently not.

Can anyone give me an explanation? Or a better workaround than
something along the line of:

Instead of:

Thanks,
 
C

Carl Banks

Hello

I stumpled upon this "feature" during my work tonight, and found it
a bit confusing:


... class C:
... foobar = 42
...>>> class B(A): pass
...

<class __main__.C at 0xb7cf735c>>>> B.C



60

When I inherit B from A, I would expect that A.C and B.C would be two
different classes? But apparently not.

No, when a class inherits a class member from a subclass, both classes
reference the same object. This is true of any object: classes,
lists, sets, etc. For instance, if you were to do this,

class A(object):
class C(object): pass
d = [1,2,3,4]
e = set(("a","b","c","d"))

class B(A):
pass


Then you would find that

A.C is B.C
A.d is B.d
A.e is B.e

They are all the same object.

Perhaps you are misled by the example methods? Even them, the same
function object is referenced by both classes. The difference is,
when accessing a method, a class doesn't return the function object
itself, but a method object instead (which is a binding between a
function and a class, used to set the value of "self" when calling
it).

But only functions do something like that, not classes.

Can anyone give me an explanation? Or a better workaround than
something along the line of:

Well you could do this and not bother with the type call (but you'd
still have to do it by hand).

class B(A):
class C(A.C):
foobar = 60


Metaclass programming, or at least some clever properties, would be
required to do it automatically. You could try something like this
(untested) to automatically subclass any class variables that are
instances of type:


class AutoSubclassMetaclass(type):
def __new__(cls,name,bases,clsdict):
for key,value in clsdict.iteritems():
if isinstance(value,type):
clsdict[key] = type(value.__name__,(value,),{})
type.__new__(cls,name,bases,clsdict)


class A(object):
__metaclasS__ = AutoSubclassMetaclass
class C(object):
foobar = 40

class B(A):
pass


Carl Banks
 
D

Diez B. Roggisch

Christian said:
Hello

I stumpled upon this "feature" during my work tonight, and found it
a bit confusing:

... class C:
... foobar = 42
...
60

When I inherit B from A, I would expect that A.C and B.C would be two
different classes? But apparently not.

Can anyone give me an explanation? Or a better workaround than
something along the line of:

Why should they be different? The class-statment of A is only exectuted
once, as is the nested class' C. Which makes A.C just a "normal"
class-variable. That is of course shared amongst subclasses. As are
methods, properties and every other thing living in the A.__dict__ due
to the MRO in python.

The more important question is: what do you need C for? Do you have by
any chance a Java-background and think of C as inner/nested class as in
Java? This feature doesn't exist in Python.

Your workaround might be implementable using a metaclass in a more
conveinient way, but I'm not sure-footed enough with metaclasses to
provide a solution out of my head now.

Diez
 
C

Christian Joergensen

[...]
No, when a class inherits a class member from a subclass, both classes
reference the same object. This is true of any object: classes,
lists, sets, etc. For instance, if you were to do this,

class A(object):
class C(object): pass
d = [1,2,3,4]
e = set(("a","b","c","d"))

class B(A):
pass


Then you would find that

A.C is B.C
A.d is B.d
A.e is B.e

They are all the same object.

I see.
Perhaps you are misled by the example methods? Even them, the same
function object is referenced by both classes. The difference is,
when accessing a method, a class doesn't return the function object
itself, but a method object instead (which is a binding between a
function and a class, used to set the value of "self" when calling
it).

But only functions do something like that, not classes.

Great explanation. This makes sense. I didn't think of it that way.

[...]
Metaclass programming, or at least some clever properties, would be
required to do it automatically. You could try something like this
(untested) to automatically subclass any class variables that are
instances of type:


class AutoSubclassMetaclass(type):
def __new__(cls,name,bases,clsdict):
for key,value in clsdict.iteritems():
if isinstance(value,type):
clsdict[key] = type(value.__name__,(value,),{})
type.__new__(cls,name,bases,clsdict)


class A(object):
__metaclasS__ = AutoSubclassMetaclass
class C(object):
foobar = 40

class B(A):
pass

Intriguing :)

Thank you for your timed,
 
C

Christian Joergensen

[...]
The more important question is: what do you need C for? Do you have by
any chance a Java-background and think of C as inner/nested class as
in Java? This feature doesn't exist in Python.

I was working on some framework code where each class would have a
nested class containing meta information about the outer class
(because all properties would be treated in a special way by the
framework).

I needed to inherit two classes and got confused when they didn't
inherit their meta information - but referenced it :)
Your workaround might be implementable using a metaclass in a more
conveinient way, but I'm not sure-footed enough with metaclasses to
provide a solution out of my head now.

That would be fun ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,254
Latest member
Top Crypto TwitterChannel

Latest Threads

Top