class object's attribute is also the instance's attribute?

É

陈伟

when i write code like this:

class A(object):

d = 'it is a doc.'


t = A()

print t.__class__.d
print t.d

the output is same.

so it means class object's attribute is also the instance's attribute. is it right? i can not understand it.
 
M

Marco Nawijn

when i write code like this:



class A(object):



d = 'it is a doc.'





t = A()



print t.__class__.d

print t.d



the output is same.



so it means class object's attribute is also the instance's attribute. isit right? i can not understand it.

I think the best way is to think of it as a global attribute restricted to the class A. Note that you even don't need an instance to get the value of the attribute. You can directly get it from the class itself.
'my attribute'

Note that if you change 'd' it will change for all instances!'my attribute'
'oops...attribute changed'
'oops...attribute changed'

If you want attributes to be local to the instance, you have to define themin the __init__ section of the class like this:

class A(object):

def __init__(self):
d = 'my attribute'
'my attribute'
'my attribute'
'oops...attribute changed'
'my attribute'

Regards,

Marco
 
O

Oscar Benjamin

If you want attributes to be local to the instance, you have to
define them in the __init__ section of the class like this:
class A(object):
def __init__(self):
d = 'my attribute'

Except that in this case you'd need to do:
self.d = 'my attribute'

Oscar
 
H

Hans Mulder

Note that if you change 'd' it will change for all instances!

That depends on how you change it.
'my attribute'

Here you change the attribute on the class.
That will affect all instances:
'oops...attribute changed'

'oops...attribute changed'

You can also set the attribute on an instance:
'oops...attribute changed'

So, if you specifically change it on one instance, thenit won't
change on other instances of the same class.
If you want attributes to be local to the instance, you have
to define them in the __init__ section of the class like this:

That's a good idea, but it's not required. You can set them
later, as shown above.

class A(object):

def __init__(self):
d = 'my attribute'

That will just set the global variable d.
You want to set the instance attribute:

self.d = 'my attribute'
'my attribute'

Note that aobj.d will not find the global variable d,
if neither the instance, nor the class nor any of the
base classes have that attribute.

I don't know where this 'my attribute' comes from, but
it's not the instance attribute you tried to set in the
__init__ method. Maybe your class A still has a class
attribute with that value from an earlier experiment.


Hope this helps,

-- HansM
 
M

Marco Nawijn

That depends on how you change it.







Here you change the attribute on the class.

That will affect all instances:







You can also set the attribute on an instance:




'For bobj only'





So, if you specifically change it on one instance, thenit won't

change on other instances of the same class.







That's a good idea, but it's not required. You can set them

later, as shown above.









That will just set the global variable d.

You want to set the instance attribute:



self.d = 'my attribute'






Note that aobj.d will not find the global variable d,

if neither the instance, nor the class nor any of the

base classes have that attribute.



I don't know where this 'my attribute' comes from, but

it's not the instance attribute you tried to set in the

__init__ method. Maybe your class A still has a class

attribute with that value from an earlier experiment.





Hope this helps,



-- HansM

Learned my lesson today. Don't assume you know something. Test it first ;).I have done quite some programming in Python, but did not know that class attributes are still local to the instances. It is also a little surprisingI must say. I always considered them like static variables in C++ (not that I am an expert in C++).

I knew of course that you don't have to define a local attribute in the __init__ method of a class, but I consider it good style and since the OP is aself claimed newbie I left out the other option.

The missing "self" in the code below was a typo
class A(object):

def __init__(self):
d = 'my attribute' # should be self.d

Regards,

Marco
 
D

Dave Angel

Learned my lesson today. Don't assume you know something. Test it first ;). I have done quite some programming in Python, but did not know that class attributes are still local to the instances.

They're not. They're just visible to the instances, except where the
instance has an instance attribute of the same name. Don't be confused
by dir(), which shows both instance and class attributes.

Please show me an example where you think you observe each instance
getting a copy of the class attribute. There's probably some other
explanation.
 
M

Marco Nawijn

They're not. They're just visible to the instances, except where the

instance has an instance attribute of the same name. Don't be confused

by dir(), which shows both instance and class attributes.



Please show me an example where you think you observe each instance

getting a copy of the class attribute. There's probably some other

explanation.

I don't have an example. It was just what I thought would happen. Consider the following. In a class declaration like this:

class A(object):
attr_1 = 10

def __init__(self):
self.attr_2 = 20

If I instantiated it twice:

obj_1 = A()
obj_2 = A()

For both obj_1 and obj_2 attr_1 equals 10. What I thought would happen after the following statement:

obj_1.attr_1 = 12

is that obj_2.attr_1 also equals 12. This is what surprised me a little, that's all.

Marco
 
M

Marco Nawijn

They're not. They're just visible to the instances, except where the

instance has an instance attribute of the same name. Don't be confused

by dir(), which shows both instance and class attributes.



Please show me an example where you think you observe each instance

getting a copy of the class attribute. There's probably some other

explanation.

I don't have an example. It was just what I thought would happen. Consider the following. In a class declaration like this:

class A(object):
attr_1 = 10

def __init__(self):
self.attr_2 = 20

If I instantiated it twice:

obj_1 = A()
obj_2 = A()

For both obj_1 and obj_2 attr_1 equals 10. What I thought would happen after the following statement:

obj_1.attr_1 = 12

is that obj_2.attr_1 also equals 12. This is what surprised me a little, that's all.

Marco
 
D

Dave Angel

I don't have an example. It was just what I thought would happen. Consider the following. In a class declaration like this:

class A(object):
attr_1 = 10

def __init__(self):
self.attr_2 = 20

If I instantiated it twice:

obj_1 = A()
obj_2 = A()

For both obj_1 and obj_2 attr_1 equals 10. What I thought would happen after the following statement:

obj_1.attr_1 = 12

is that obj_2.attr_1 also equals 12. This is what surprised me a little, that's all.

Marco

That statement only adds an instance attribute, not modifying the class
attribute of the same name. But it does "hide" it from that particular
instance.

The thing that can be surprising is that if the class attribute is
mutable, and you mutate it, rather than assigning it. So for example:

class A(object):
attr_1 = [10, 9]

def __init__(self):
self.attr_2 = 20


obj_1 = A()
obj_2 = A()

obj_1.attr_1.append(3)

Then I believe you'll see [10, 9, 3] from both instances.
print obj_1.attr_1
print obj_2.attr_1
 
H

Hans Mulder

A very important lesson.

Next week's lesson will be: if you test it first, then
paste it into a message for this forum, then tweak just
one unimportant detail, you'll need to test it again.
I don't have an example. It was just what I thought would happen.
Consider the following. In a class declaration like this:

class A(object):
attr_1 = 10

def __init__(self):
self.attr_2 = 20

If I instantiated it twice:

obj_1 = A()
obj_2 = A()

For both obj_1 and obj_2 attr_1 equals 10. What I thought would happen after the following statement:

obj_1.attr_1 = 12

is that obj_2.attr_1 also equals 12. This is what surprised me a little, that's all.

The trick is to look at obj_1.__dict__ to see what is defined locally:
{'attr_2': 20}
{'attr_2': 20, 'attr_1': 12}


Hope this helps,

-- HansM
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top