-4

Given

class A:
    x = 'Ac'
    def f(self):
        return self.x

class B(A):
    x = 'Bc'
    def f(self):
        return self.x

class C(A):
    x = 'Cc'
    def f(self):
        return self.x

class D(B, C):
    x = 'Dc'
    def __init__(self):
        self.x = 'Di'
    def f(self):
        return self.x

d = D()
  1. What is the name resolution order for d.x? E.g. Di, Dc, Bc, Cc, Ac

  2. What is the name resolution order for super(D, d).x?

  3. What is the nro for self.x in super(D, d).f()? Is it the same as for d.f()?

  4. What is the nro for D.x?

  5. If I assign to d.x and Di wasn't there, where will it go? E.g. Di or Dc

  6. If I assign to D.x and Dc wasn't there, where will it go?

  7. If I assign to super(D, d).x and Bc wasn't there, where will it go? E.g. Di or Dc or Bc

darkfeline
  • 9,404
  • 5
  • 31
  • 32
  • Wuh? Why do my questions always get downvoted immediately with no apparent reason? Could you guys at least leave a comment so I know why? – darkfeline Sep 20 '12 at 20:29
  • 1
    Every one of your questions above could be answered by writing an appropriate bit of code and trying it. There doesn't appear to be any effort on your part to understand anything about what you're asking. – Greg Hewgill Sep 20 '12 at 20:35
  • @GregHewgill: I think you're being a bit too harsh. Inexperienced programmers may not know how to write code to answer this type of question, or don't yet have the mind-set of "experiment first, ask second". I agree the question could be better written, but a score of -3 (at the time I write this) is disproportionately low. – Bryan Oakley Sep 20 '12 at 20:41
  • I had a hard enough time just trying to describe what I wanted to know. Should I have phrased the question instead: How would I write code to test the following cases? I'd imagine a direct answer would be more useful. – darkfeline Sep 20 '12 at 20:47
  • 1
    I suspect some of the downvotes come from your questions looking suspiciously like homework. Also, you're dumping a lot of questions in the same place without providing any evidence that you tried to come up with answers yourself. Although it doesn't directly apply to StackOverflow, ESR's [essay on how to ask questions the smart way](http://www.catb.org/esr/faqs/smart-questions.html#intro) is a recommended read. – user4815162342 Sep 20 '12 at 21:00
  • Thank you for the constructive criticism. It's true I didn't do any work, but (at least for me) it would be a lot of work and if someone already knows, wouldn't it be better to put it here to save everyone who is looking for the same thing time? Rest assured it is not homework; if my CS classes were this hard I'd be overjoyed. – darkfeline Sep 20 '12 at 21:09
  • It really is worth learning how to do the work yourself. I didn't know all of the answers off the top of my head, but it only took a few minutes to figure out how to test them. I understand that someone with less experience might take more time figuring it out, but you'll learn a lot just trying to do so. – abarnert Sep 20 '12 at 21:31

2 Answers2

3

If your objects are new style objects (inherit from object), you can print out the method resolution order by using the __mro__ attribute or mro method to get your answers.

Modify class A to look like this:

class A(object):
    ...

Then you can print out the method resolution order of each class:

>>> A.__mro__
(<class 'junk.A'>, <type 'object'>)
>>> B.__mro__
(<class 'junk.B'>, <class 'junk.A'>, <type 'object'>)
>>> C.__mro__
(<class 'junk.C'>, <class 'junk.A'>, <type 'object'>)
>>> D.__mro__
(<class 'junk.D'>, <class 'junk.B'>, <class 'junk.C'>, <class 'junk.A'>, <type 'object'>)

The stackoverflow question Method Resolution Order (MRO) in new style Python classes has some useful information.

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Actually, I'm aware of this, but I'm talking about attributes, especially instance attributes vs. class attributes through a inheritance tree which I'm uncertain about. For example, if I want d.x, does it look for instance attributes or class attributes first in what order up the inheritance tree? Ditto for if I want to set x. – darkfeline Sep 20 '12 at 20:45
2

First, it would make things a whole lot easier if you assigned different values at each point instead of None everywhere. But I'll try to answer your question as asked.

The first thing to note is that the d instance actually only has 1 copy of x, not 4. You can test this pretty easily:

>>> d.x = 3
>>> B.f(d)
3

In a language like C++, the output would have been None, because D has separate B::x, C::x, and D::x data members. (I'm pretending here that A doesn't exist, because it makes things much more complicated to discuss, and isn't actually relevant to the question.)

Or, even more easily:

>>> dir(d)
['__doc__', '__init__', '__module__', 'f', 'x']

That's all the members there are; you've assigned to the same self.x four times.

Classes, on the other hand, do each have their own copy. If there's no instance variable, these are searched in the same order as the mro. Which again you can test easily:

>>> del d.x
>>> B.x = 4
>>> C.x = 5
>>> D.x = 6
>>> d.f()
6
>>> C.f(d)
6
>>> del D.x
>>> d.f()
4

As for setting, that's easy: setting d.x always sets the instance variable (remember, there's only 1 of them, not 4), or creates it if none exists. Meanwhile, setting D.x or B.x sets or creates the class variable for that class. So, the inheritance hierarchy is irrelevant.

abarnert
  • 354,177
  • 51
  • 601
  • 671