473,779 Members | 2,047 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Need a better understanding on how MRO works?

Given the following code: (I hope it's as simple as possible) :-)
#! /usr/bin/python
import new
class BASE:
def __init__( self ):
print 'Hello from BASE init'
def m1( self ):
print 'M1 Base: Self = ', self

def m1replace( self ):
print 'm1replace:Self = ', self

class D1(BASE):
def __init__(self):
BASE.__init__(s elf)

def __InitDS101Clas ses():
name = 'C1'
nclass = new.classobj(na me,(D1,),global s())
globals()[name] = nclass
name = 'C2'
nclass = new.classobj(na me,(D1,),global s())
globals()[name] = nclass
globals()[name].m1 = m1replace

__InitDS101Clas ses()

s = C1()
s.m1()
t = C2()
t.m1()

I get the following output:

1100 ./foo1.py
Hello from BASE init
m1replace:Self = <__main__.C1 instance at 0xb7e637cc>
Hello from BASE init
m1replace:Self = <__main__.C2 instance at 0xb7e6388c>

But if I make BASE inherit from object
class BASE(object):
then I get this:

1100 ./foo1.py
Hello from BASE init
m1replace:Self = <__main__.NewCl ass instance at 0xb7f5070c>
Hello from BASE init
M1 Base: Self = <__main__.D1 instance at 0xb7f5088c>

Can someone please explain why the assignment to C2.m1 would overwrite
BASE.m1?

TIA

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
Aug 25 '07 #1
6 1409
Steven W. Orr <st****@syslang .netwrote:
...
name = 'C1'
nclass = new.classobj(na me,(D1,),global s())
globals()[name] = nclass
Here, you're creating a VERY anomalous class C1 whose __dict__ is
globals(), i.e. the dict of this module object;
name = 'C2'
nclass = new.classobj(na me,(D1,),global s())
globals()[name] = nclass
and here you're creating another class with the SAME __dict__;
globals()[name].m1 = m1replace
So of course this assignment affects the 'm1' entries in the dict of
both classes, since they have the SAME dict object (a la Borg) -- that
is, IF they're old-style classes (i.e. if D1 is old-style), since in
that case a class's __dict__ is in fact a dict object, plain and simple.

However, if D1 is new-style, then C1.__dict__ and C2.__dict__ are in
fact instances of <dictproxy-- each with a copy of the entries that
were in globals() when you called new.classobj, but DISTINCT from each
other and from globals(), so that further changes in one (or globals)
don't affect globals (nor the other).

I guess this might be a decent interview question if somebody claims to
be a "Python guru": if they can make head or tails out of this mess, boy
the *ARE* a Python guru indeed (in fact I'd accord minor guruhood even
to somebody who can get a glimmer of understanding of this with ten
minutes at a Python interactive prompt or the like, as opposed to
needing to understand it "on paper" without the ability to explore:-).

Among the several "don't"s to learn from this: don't use old-style
classes, don't try to make two classes share the same dictionary, and
don't ask about MRO in a question that has nothing to do with MRO
(though I admit that was a decent attempt at misdirection, it wouldn't
slow down even the minor-guru in any appreciable way:-).
Alex
Aug 26 '07 #2
On Saturday, Aug 25th 2007 at 17:19 -0700, quoth Alex Martelli:

=>Steven W. Orr <st****@syslang .netwrote:
= ...
=> name = 'C1'
=> nclass = new.classobj(na me,(D1,),global s())
=> globals()[name] = nclass
=>
=>Here, you're creating a VERY anomalous class C1 whose __dict__ is
=>globals(), i.e. the dict of this module object;
=>
=> name = 'C2'
=> nclass = new.classobj(na me,(D1,),global s())
=> globals()[name] = nclass
=>
=>and here you're creating another class with the SAME __dict__;
=>
=> globals()[name].m1 = m1replace
=>
=>So of course this assignment affects the 'm1' entries in the dict of
=>both classes, since they have the SAME dict object (a la Borg) -- that
=>is, IF they're old-style classes (i.e. if D1 is old-style), since in
=>that case a class's __dict__ is in fact a dict object, plain and simple.
=>
=>However, if D1 is new-style, then C1.__dict__ and C2.__dict__ are in
=>fact instances of <dictproxy-- each with a copy of the entries that
=>were in globals() when you called new.classobj, but DISTINCT from each
=>other and from globals(), so that further changes in one (or globals)
=>don't affect globals (nor the other).
=>
=>I guess this might be a decent interview question if somebody claims to
=>be a "Python guru": if they can make head or tails out of this mess, boy
=>the *ARE* a Python guru indeed (in fact I'd accord minor guruhood even
=>to somebody who can get a glimmer of understanding of this with ten
=>minutes at a Python interactive prompt or the like, as opposed to
=>needing to understand it "on paper" without the ability to explore:-).
=>
=>Among the several "don't"s to learn from this: don't use old-style
=>classes, don't try to make two classes share the same dictionary, and
=>don't ask about MRO in a question that has nothing to do with MRO
=>(though I admit that was a decent attempt at misdirection, it wouldn't
=>slow down even the minor-guru in any appreciable way:-).
=>
=>
=>Alex
=>--
=>http://mail.python.org/mailman/listinfo/python-list
=>

Thanks Alex. I am humbled, though I was before I started.
I really don't have a lot of understanding of what you're saying so I'll
probably have to study this for about a year or so.

* (I need to look up what dictproxy is.) I don't have any idea what the
ramifications are of your use of the word DISTINCT. Are you somehow
suggesting that new.classobj does a deep copy of the globals copy that's
passed to it?

* Also, I'd like to understand what the difference is between
nclass = new.classobj(na me,(D1,),global s())
vs.
def classfactory():
class somename(object ):
def somestuff():
pass
return somename
G1 = classfactory()
globals()[name] = G1

Does new.classobj do anything special?

I appreciate your time.

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
Aug 26 '07 #3
Steven W. Orr <st****@syslang .netwrote:
...
Thanks Alex. I am humbled, though I was before I started.
I really don't have a lot of understanding of what you're saying so I'll
probably have to study this for about a year or so.

* (I need to look up what dictproxy is.) I don't have any idea what the
ramifications are of your use of the word DISTINCT. Are you somehow
suggesting that new.classobj does a deep copy of the globals copy that's
passed to it?
No, most definitely NOT deep!!!, but type.__new__ does "a little" of
what you've said (a shallow copy, which is not quite "a copy" because it
embeds [some of] the entries in slots). new.classobj determines the
metaclass (from the bases, or a __metaclass__ entry in the dictionary)
and calls it to generate the new class. For modern style classes, the
class is type; for old-style legacy classes, it's types.ClassType , and
they're not exactly identical in behavior (of course not, or there would
no point in having both:-).
>
* Also, I'd like to understand what the difference is between
nclass = new.classobj(na me,(D1,),global s())
vs.
def classfactory():
class somename(object ):
def somestuff():
pass
return somename
G1 = classfactory()
globals()[name] = G1

Does new.classobj do anything special?
No, new.classobj does essentially the same thing that Python does after
evaluating a class statement to prepare the class's name, bases and
dictionary: finds the metaclass and calls it with these arguments.

A key difference of course is that a class statement prepares the class
dictionary as a new, ordinary, distinct dictionary, while new.classobj
accepts whatever dictionary you give it (so you can, though shouldn't,
do strange things such as pass globals()...:-).
Alex
Aug 26 '07 #4
On Saturday, Aug 25th 2007 at 22:14 -0700, quoth Alex Martelli:

=>Steven W. Orr <st****@syslang .netwrote:

=>* Also, I'd like to understand what the difference is between
=> nclass = new.classobj(na me,(D1,),global s())
=>vs.
=> def classfactory():
=> class somename(object ):
=> def somestuff():
=> pass
=> return somename
=> G1 = classfactory()
=> globals()[name] = G1
=>>
=>Does new.classobj do anything special?
=>
=>No, new.classobj does essentially the same thing that Python does after
=>evaluating a class statement to prepare the class's name, bases and
=>dictionary: finds the metaclass and calls it with these arguments.
=>
=>A key difference of course is that a class statement prepares the class
=>dictionary as a new, ordinary, distinct dictionary, while new.classobj
=>accepts whatever dictionary you give it (so you can, though shouldn't,
=>do strange things such as pass globals()...:-).

In fact, I wanted to make a common routine that could be called from
multiple modules. I have classes that need to be created from those
multiple modules. I did run into trouble when I created a common routine
even though I passed globals() as one of the args. The """though
shouldn't""" is prompting me to ask why, and where I might be able to read
more.

--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
Aug 26 '07 #5
Steven W. Orr <st****@syslang .netwrote:
...
=>accepts whatever dictionary you give it (so you can, though shouldn't,
=>do strange things such as pass globals()...:-).

In fact, I wanted to make a common routine that could be called from
multiple modules. I have classes that need to be created from those
multiple modules. I did run into trouble when I created a common routine
even though I passed globals() as one of the args. The """though
shouldn't""" is prompting me to ask why, and where I might be able to read
more.
The dictionary you pass to new.classobj should be specifically
constructed for the purpose -- globals() will contains all sort of odds
and ends that have nothing much to do with the case.

You appear to be trying to embody lot of black magic in your "common
routine", making it communicate with its callers by covert channels; the
way you use globals() to give that routine subtle "side effects" (making
the routine stick entries there) as well as pass it an opaque,
amorphous, unknown blobs of input information, strongly suggests that
the magic is running away with you (a good general reference about that
is <http://video.google.co m/videoplay?docid =46114915250285 88899>).

"Explicit is better than implicit", "simple is better than complex",
etc, can be read by typing ``import this'' at an interactive Python
prompt.

The best book I know about the do's and don't's of large-scale software
architecture is Lakos' "Large-Scale C++ Software Design",
<http://www.amazon.com/Large-Scale-So...kos/dp/0201633
620-- very C++ specific, but even though some of the issues only apply
to C++ itself, many of its crucial lessons will help with large scale SW
architecture in just about any language, Python included.

What I had to say about the lures and pitfalls of black magic in Python
specifically is spread through the Python Cookbook 2nd edition (and, to
a lesser extent, Python in a Nutshell).
Alex
Aug 26 '07 #6
On Sun, 26 Aug 2007 07:55:39 -0400, Steven W. Orr wrote:
In fact, I wanted to make a common routine that could be called from
multiple modules. I have classes that need to be created from those
multiple modules. I did run into trouble when I created a common routine
even though I passed globals() as one of the args.
I'm thinking that you should cross out "even though" and insert
"because" :-)

Perhaps I'm misunderstandin g exactly what you're trying to accomplish,
but if you want to call a routine (a function? class?) from multiple
modules, the simplest way is the best: create the routine in one module,
then import it into all the others.

--
Steven.
Aug 26 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
3137
by: netpurpose | last post by:
I need to extract data from this table to find the lowest prices of each product as of today. The product will be listed/grouped by the name only, discarding the product code - I use SUBSTRING(ProductName, 1, CHARINDEX('(', ProductName)-2). I can get this result, but I had to use several views (totally inefficient). I think this can be done in one efficient/fast query, but I can't think of one. In the case that one query is not...
4
3130
by: Muhd | last post by:
It seems like im missing something, what i want to do is select the last row from a table that relates to a specific person. My table and select statement follow, the select statement works fine, works great as a matter of fact, but i feel as if i am missing something (well something in addition to a better understanding of sql but im still working on that). CREATE TABLE Logins ( ID IDENTITY(1,1) PRIMARY KEY Username VARCHAR(100),
19
4109
by: James Fortune | last post by:
I have a lot of respect for David Fenton and Allen Browne, but I don't understand why people who know how to write code to completely replace a front end do not write something that will automate the code that implements managing unbound controls on forms given the superior performance of unbound controls in a client/server environment. I can easily understand a newbie using bound controls or someone with a tight deadline. I guess I need...
7
2185
by: Buck Rogers | last post by:
Hi all! Newbie here. Below is an example from Teach Yourself C in 21 Days. My apologies if it is a bit long. What I don't understand is how the "get_data" function can call the "continue_function", and if NO is returned to "get_data", display_report executes and the program ends? Basically I am having trouble understanding the program flow within the "if" loop in the "main" function.
5
3373
by: Y2J | last post by:
I am working through this book on C++ programming, the author is speaking of using linked lists. He gave and example which I found confusing to say the least. So I rewrote the example in a way that I could better understand the concept, he was trying to convey to me. I ran my own example and it crashed and burn "what a surprise!" : (. I ran the authors example out of the book and quess what, it crashed also, : 0. I ran them both on my...
22
2723
by: JoeC | last post by:
I am working on another game project and it is comming along. It is an improvment over a previous version I wrote. I am trying to write better programs and often wonder how to get better at programming. I tend to learn what is useful and gets the job done. I am always curious if there is some techique I don't know. I read books and study as well as write programs. My goal is to some day be able to get a job programming. I have a...
9
1325
by: sam_cit | last post by:
Hi Everyone, I have the following structure and i have a function that will work(modify/edit) the members of the structure, please tell me which is a better apprach considering both time and memory complexity, struct sample { char* string; int n;
15
2258
RMWChaos
by: RMWChaos | last post by:
In my ongoing effort to produce shorter, more efficient code, I have created a "chicken and egg" / "catch-22" problem. I can think of several ways to fix this, none of them elegant. I want my code to declare var stop if it was not passed to the function. The problem is that stop would be equal to a value dependent on var index that has not been declared yet, but index cannot be created until stop is declared. So you see my chicken and egg...
0
9632
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10302
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10136
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9925
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8958
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7478
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6723
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
3631
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2867
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.