473,549 Members | 2,651 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Setting Class Attributes

I have a small, simple class which contains a dictionary (and some
other stuff, not shown). I then have a container class (Big) that holds
some instances of the simple class. When I try to edit the elements of
the dictionary, all instances obtain those changes; I want each
instance to hold separate entries.

#----------Begin module test.py
class ex:
def __init__(self, val={}):
self.value = val
def __str__(self):
return str(self.value)

class Big:
def __init__(self):
self.A = ex()
self.B = ex()
def __str__(self)
return "A=%s, B=%s"%(self.A, self.B)
def changea(self):
a = self.A.value
a['x'] = 1
a['y'] = 10

print "x = Big()"
x = Big()
print x

print "x.changea( )"
x.changea()
print x

print "x.B.value = 30"
x.B.value = 30
print x
#----------End module test.py

#----------Begin actual output
x = Big()
A={}, B={}
x.changea()
A={'x':1, 'y':10}, B={'x':1, 'y':10}
x.B.value = 30
A={'x':1, 'y':10}, B=30
#----------End actual output

#----------Begin Desired output
x = Big()
A={}, B={}
x.changea()
A={'x':1, 'y':10}, B={}
x.B.value = 30
A={'x':1, 'y':10}, B=30
#----------End Desired output

I'm never actually planning on changing the dictionary into something
else, I just included that test to see wether both A and B would be set
to 30. I'm clearly missing something here: Why do both dictionaries
appear to get the same data when they are clearly separate instances?

Oct 25 '05 #1
6 1728
the.theorist a écrit :
I have a small, simple class which contains a dictionary (and some
other stuff, not shown). I then have a container class (Big) that holds
some instances of the simple class. When I try to edit the elements of
the dictionary, all instances obtain those changes; I want each
instance to hold separate entries.

#----------Begin module test.py
class ex:
class ex(object): # oldstyle classes are deprecated
def __init__(self, val={}):
self.value = val


You didn't search very long. This is one of the most (in)famous Python
gotchas: default args are evaluated *only once*, when the function
definition is evaluated (at load time). This is also a dirty trick to
have a 'static' (as in C) like variable.

The solution is quite simple:
class ex(object):
def __init__(self, val=None):
if val is None: val = {}
self.value = val

(snip)
Oct 25 '05 #2

Bruno Desthuilliers wrote:
the.theorist a écrit :
I have a small, simple class which contains a dictionary (and some
other stuff, not shown). I then have a container class (Big) that holds
some instances of the simple class. When I try to edit the elements of
the dictionary, all instances obtain those changes; I want each
instance to hold separate entries.

#----------Begin module test.py
class ex:


class ex(object): # oldstyle classes are deprecated
def __init__(self, val={}):
self.value = val


You didn't search very long. This is one of the most (in)famous Python
gotchas: default args are evaluated *only once*, when the function
definition is evaluated (at load time). This is also a dirty trick to
have a 'static' (as in C) like variable.

The solution is quite simple:
class ex(object):
def __init__(self, val=None):
if val is None: val = {}
self.value = val

(snip)


Hey, that was extremely helpful. I suspect that the default args
evaluation is optimized for speed. So it makes sense to use the None
assignment, and a test condition later.

Worked like a charm, Thanks!

Oct 25 '05 #3
On 25 Oct 2005 15:57:41 -0700, "the.theori st" <th**********@g mail.com> wrote:

Bruno Desthuilliers wrote:
the.theorist a =E9crit :
> I have a small, simple class which contains a dictionary (and some
> other stuff, not shown). I then have a container class (Big) that holds
> some instances of the simple class. When I try to edit the elements of
> the dictionary, all instances obtain those changes; I want each
> instance to hold separate entries.
>
> #----------Begin module test.py
> class ex:
class ex(object): # oldstyle classes are deprecated
> def __init__(self, val=3D{}):
> self.value =3D val


You didn't search very long. This is one of the most (in)famous Python
gotchas: default args are evaluated *only once*, when the function
definition is evaluated (at load time). This is also a dirty trick to
have a 'static' (as in C) like variable.

The solution is quite simple:
class ex(object):
def __init__(self, val=3DNone):
if val is None: val =3D {}
self.value =3D val

(snip)


Hey, that was extremely helpful. I suspect that the default args
evaluation is optimized for speed. So it makes sense to use the None
assignment, and a test condition later.

That sounds like you missed the important point: The reason for using None
instead of {} as a default argument is that default arguments are only
evaluated when the function is defined, not when it's called, so if the
default value is {}, that very _same_ dict will be used as default for
the next call to __init__, so you will have every instance of ex looking
at the same val and binding it to its self.value, and then if one instance
modifies it (which it can, since a dict is mutable), the other instances
will see the modification in their self.value dicts. The None default
prevents re-use of a dict that wasn't actually passed in as an argument
replacing the default in the call. The call-time test for None discovers
that a fresh dict is needed, and self.value = {} creates that fresh dict
when __init__ executes, so the new instance gets its own separate self.value dict.

Nothing to do with optimization. In fact, re-using the shared default dict
would be faster, though of course generally wrong.
Worked like a charm, Thanks!

Just wanted to make sure you realize why it made a difference, in case ;-)

Regards,
Bengt Richter
Oct 26 '05 #4
So that it'll be easier to remember the next time I find myself in the
same situation on a different task, I'll extend the discussion
somewhat.

Coming from C, I had expected that I'd get a new empty dict every time
the __init__ function ran. Guido (or some other benevolent) had decided
to implement things a little bit differently in Python. I understand
that most everything is a pointer in Python. (which gives us cool stuff
like recursive data structures) So I was wondering, they could have
made the behavior C-like, but chose not to. The decision to bind
everything in the function to the same default args must be a
reflection of the Python Ideology. Philosophically , why was it done
this way, and how does it fit in with Python's design as a language.

(hopefully, reasons will help me remeber why things are the way they
are, so I don't forget in the future)
-----------------
I've only been using Python for a few weeks. (Chose it over Perl,
because Python syntax is cleaner). I really like Python (over C), as it
makes coding and debugging much faster and easier.

Oct 26 '05 #5
the.theorist wrote:
So that it'll be easier to remember the next time I find myself in the
same situation on a different task, I'll extend the discussion
somewhat.

Coming from C, I had expected that I'd get a new empty dict every time
the __init__ function ran. Guido (or some other benevolent) had decided
to implement things a little bit differently in Python. I understand
that most everything is a pointer in Python. (which gives us cool stuff
like recursive data structures) So I was wondering, they could have
made the behavior C-like, but chose not to. The decision to bind
everything in the function to the same default args must be a
reflection of the Python Ideology. Philosophically , why was it done
this way, and how does it fit in with Python's design as a language.
I couldn't claim to be channelling the developers, but I suspect that
the decision was pragmatic.

Consider what would have to be done in the case of a method prototype
such as

class myClass(object) :
def __init__(arg1, arg2=default):
print "Arg2 is:", arg2

Remember as well that the "def" statement is executable: when executed
it binds the function name to the compiled function body in the current
namespace.

Suppose the "default" name had gone out of scope by the time the
instances are created: what value would you have the ionterpreter bind
to the argument in that case?
(hopefully, reasons will help me remeber why things are the way they
are, so I don't forget in the future)
-----------------
I've only been using Python for a few weeks. (Chose it over Perl,
because Python syntax is cleaner). I really like Python (over C), as it
makes coding and debugging much faster and easier.

Yup, it's a great languae, and it seems to be increasing in popularity
quite rapidly.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Oct 26 '05 #6


the.theorist wrote:
So that it'll be easier to remember the next time I find myself in the
same situation on a different task, I'll extend the discussion
somewhat.

Coming from C, I had expected that I'd get a new empty dict every time
the __init__ function ran. Guido (or some other benevolent) had decided
to implement things a little bit differently in Python. I understand
that most everything is a pointer in Python. (which gives us cool stuff
like recursive data structures) So I was wondering, they could have
made the behavior C-like, but chose not to. The decision to bind
everything in the function to the same default args must be a
reflection of the Python Ideology. Philosophically , why was it done
this way, and how does it fit in with Python's design as a language.
I didn't read too closely the thread leading up to this point so I may
be stating something already stated or that is already obvious to you.

There is a difference between a pointer and name binding that you should
keep in mind. When using pointers in C you can feasibly have a chain of
pointers. In Python, it doesn't work that way unless you explicitly
define a pointer type object to be used in such a way. The normal
behavior is for an expression to bind a name with the object that is
bound to the other name. So...

a = 1 # a binds to 1
b = a # b binds to 1
c = b # c binds to 1

So if you change what 'a' is bound to, 'b' and 'c' are still each bound
to 1.

Some of the places where you get pointer type behavior is in container
objects. Look at the following sequence of instructions.

a = 1 # a binds to 1
b = [a] # first item in list is bound to 1,
b binds to list.
c = b # c bind to same list b is bound to.
a = 2 # a binds to 2
print b[0] -> 1 # print first item in list b is bound to.
b[0] = 3 # change first item in list b is bound to to 3
print c[0] -> 3 # print first item in list c is bound to,
# (same list as b is bound to)

If you can follow this easily you are well on your way to understanding
Pythons storage model and philosophy. Notice, a name isn't bound to
another name.

This relationship is all over Python including the name binding of
functions and class methods. And also in class's as well.

Keep in mind the class body is executed at the time it is defined, and
the methods are defined but not executed until they are used. In the
case of the __init__ it is when the class is called after an instance
object is created. When instances are created they share any class
objects that were bound to names when the class was defined. They don't
share any objects that get bound to instance attribute names in methods
later.

Does this help any?

Cheers,
Ron
(hopefully, reasons will help me remeber why things are the way they
are, so I don't forget in the future)
-----------------
I've only been using Python for a few weeks. (Chose it over Perl,
because Python syntax is cleaner). I really like Python (over C), as it
makes coding and debugging much faster and easier.

Oct 26 '05 #7

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

Similar topics

1
1984
by: svilen | last post by:
hi. this was named but it is misleading. i want to have the order of setting items in intrinsic dicts (keyword args, or class attributes, etc). which is, a prdered dict trhat matches the source-text sequences.
4
5981
by: G. Richard Bellamy | last post by:
I'm trying to unset the Encrypted attribute on all the files in a path. The attribute is not getting set. What am I doing wrong? Perhaps there's another newsgroup I can send this to? Here's the code: ============================================= using System;
3
1464
by: AndyG | last post by:
I'm trying to mess about with a table using javascript. I'm deleting the current row then adding a new row and adding a couple of columns. I then want to add either a style attribute and add a border to the bottom of one of the cells or add a class attribute and set it up in the stylesheet. Problem is, when I try to use the setAttribute it...
21
3946
by: Michael Bierman | last post by:
Please forgive the simplicy of this question. I have the following code which attempts to determine the color of some text and set other text to match that color. It works fine in Firefox, but does nothing in IE. I'd be greatful for any assistance. Also, if I will have problems the code on Opera or Safari, I'd appreciate any pointers--I don't...
1
2449
by: Steven Quail | last post by:
Hi to all, I have just started looking at XML.Serialization classes and would like to know how I set an attribute for an XML element. For example, I want my XML doc to look like the following: <Person> <Name> <FirstName>John</FirstName>
7
12229
by: John R. | last post by:
How do you set the following file attributes: Compressed Encrypted Normal ReparsePoint SparsePoint You CAN'T set these using FileInfo.Attributes or File.SetAttributes. It doesn't work for these file attributes.
3
6730
by: Marty McFly | last post by:
Hello, I have a control class that inherits from System.Web.UI.WebControls.Button. When I drag this control from the "My User Controls" tab in the toolbox onto the form, I want it to reflect the following default properties: Height = 32px, Width = 144px. I declare the Width property in my control as... \\\
0
2636
by: David J | last post by:
Hi, I am strugling with the propertygrid and a listbox. I am using the universaldropdowneditor from the codeproject (code below). However I am populating the listbox via a datasource. The problem I am having is that when I have a value in the propertygird and edit that, I want the listbox to have the selectvalue equal to the value that is...
2
1236
by: Sam | last post by:
Hi all I'm looking for a way to detect the background color of my internal webpage through a stylesheet. And so far, the only solution I find is to open the styles.css file and parse the BACKGROUND-COLOR field. The problem I'm having is that I don't know the exact absolute path of the stylesheet file (styles.css) to access it using stream...
3
1281
by: rh0dium | last post by:
Hi all, I have the following piece of code and I wanted to set the default attributes based on a dictionary. What I am looking for is a way to take PIPODEFAULTS and assign each one as an attribute for the class pipo. Can someone show me how to do this by iterating over the PIPODEFAULTS and assign them. What I would expect to be able to do...
0
7462
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7975
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...
1
7492
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7823
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...
0
6059
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...
0
5101
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...
0
3491
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1957
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1069
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.