[Tutor] Descriptors api doubt
alan.gauld@bt.com
alan.gauld@bt.com
Tue, 15 Jan 2002 11:14:01 -0000
> For example, when you write obj.x, the steps that Python
> actually performs are:
>
> descriptor = obj.__class__.x
> descriptor.__get__(obj)
And so it does heres an example, with my comments:
>>> class C:
... name = '' ## defie a class member
... def __init__(self,n): self.name = n
## assign to it making an instance specific version
...
>>> class D:
... def __init__(self,n): self.name = n
## D only has an instance version no class member
...
>>> c = C('foo')
>>> d = D('bar')
>>> c.__class__.name
''
## The class version is unchanged
>>> c.name
'foo'
## there's the instance version
>>> d.__class__.name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: class D has no attribute 'name'
## like it says D has no class member
>>> d.name
'bar'
## but it does have an instance one.
> This is what i did:
>
> class test(object):
> def __init__(self):
> self.name = "python"
So the nself.name doesn't come into effect till after
you create an instance. The class object has no name
attribute.
> >>> t = test()
> >>> desc = t.__class__.name
> Traceback (most recent call last):
> File "<pyshell#15>", line 1, in ?
> ob = t.__class__.name
> AttributeError: type object 'test' has no attribute 'name'
Just like I said...
> if python does that internally, then why am in not able
> to access the descriptor corresponding to "name".
You can as I shoiwed but thats how Python accesses *class*
variables not *instance* variables - they are not the same.
When you define a class any attributes outside the methods
are class members and shared by all instances.
When an instance assigns to a class member name python
creates a new instance specific member which is accessible
to that instance only.
class X:
foo = 0
def setFoo(self,x): self.foo = x
a = X()
b = X() # two instances
print a.foo, b.foo ### => 0 0
X.foo = 7 # change shared value
print a.foo, b.foo ### => 7 7
a.setFoo(5) # create new copy in 'a' only
print a.foo, b.foo ### => 5 7 ie b still using shared one
X.foo = 42 # change shared one
print a.foo, b.foo ### => 5 42 change only seen by b
HTH,
Alan G.