Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #17337 > unrolled thread

Class: @property -> .__dict__

Started byUlrich <ulrich@dorda.net>
First post2011-12-16 00:52 -0800
Last post2011-12-16 11:02 +0100
Articles 7 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  Class: @property -> .__dict__ Ulrich <ulrich@dorda.net> - 2011-12-16 00:52 -0800
    Re: Class: @property -> .__dict__ Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-16 09:03 +0000
      Re: Class: @property -> .__dict__ Ulrich <ulrich.dorda@gmail.com> - 2011-12-16 01:11 -0800
        Re: Class: @property -> .__dict__ Ulrich <ulrich.dorda@gmail.com> - 2011-12-16 01:14 -0800
          Re: Class: @property -> .__dict__ Peter Otten <__peter__@web.de> - 2011-12-16 10:32 +0100
          Re: Class: @property -> .__dict__ Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-16 09:23 -0700
    Re: Class: @property -> .__dict__ Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2011-12-16 11:02 +0100

#17337 — Class: @property -> .__dict__

FromUlrich <ulrich@dorda.net>
Date2011-12-16 00:52 -0800
SubjectClass: @property -> .__dict__
Message-ID<ad04c206-dbfd-4e49-b365-943b47844c41@n6g2000vbg.googlegroups.com>
Good morning,

I wonder if someone could please help me out with the @property
function as illustrated in the following example.

class te():
    def __init__(self):
        self.a = 23
    @property
    def b(self):
        return 2 * self.a


t = te()
In [4]: t.a
Out[4]: 23

In [5]: t.b
Out[5]: 46

#works asexpected so far, now let's have a look into t.__dict__
In [6]: t.__dict__
Out[6]: {'a': 23}
-> b does not show up.

Could anyone please explain me why this does not work / how to get b
into .__dict__ / hint me to an explanation?

Thanks a lot in advance!

Cheers,

Ulrich

[toc] | [next] | [standalone]


#17338

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-12-16 09:03 +0000
Message-ID<4eeb0949$0$29979$c3e8da3$5496439d@news.astraweb.com>
In reply to#17337
On Fri, 16 Dec 2011 00:52:11 -0800, Ulrich wrote:

> Good morning,
> 
> I wonder if someone could please help me out with the @property function
> as illustrated in the following example.
> 
> class te():
>     def __init__(self):
>         self.a = 23
>     @property
>     def b(self):
>         return 2 * self.a
[...]
> Could anyone please explain me why this does not work / how to get b
> into .__dict__ / hint me to an explanation?

b is a property object. Like any other assignment inside the body of the 
class, it is shared across all instances, so you won't find it in the 
instance's personal dict. You will find it in the shared class dict.

t.__dict__['b']  # not found
te.__dict__['b']  # will return the property object

(By the way: it is the usual convention to start the name of a class with 
initial capital, so Te would be a better name.)

To get something into the instance dict, you need to assign it onto the 
instance:

t.x = 42  # puts 'x':42 into t.__dict__


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#17339

FromUlrich <ulrich.dorda@gmail.com>
Date2011-12-16 01:11 -0800
Message-ID<3fe1021b-75ae-4e3d-a5b0-175ad00aefa4@i6g2000vbh.googlegroups.com>
In reply to#17338
On Dec 16, 10:03 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:
> On Fri, 16 Dec 2011 00:52:11 -0800, Ulrich wrote:
> > Good morning,
>
> > I wonder if someone could please help me out with the @property function
> > as illustrated in the following example.
>
> > class te():
> >     def __init__(self):
> >         self.a = 23
> >     @property
> >     def b(self):
> >         return 2 * self.a
> [...]
> > Could anyone please explain me why this does not work / how to get b
> > into .__dict__ / hint me to an explanation?
>
> b is a property object. Like any other assignment inside the body of the
> class, it is shared across all instances, so you won't find it in the
> instance's personal dict. You will find it in the shared class dict.
>
> t.__dict__['b']  # not found
> te.__dict__['b']  # will return the property object
>
> (By the way: it is the usual convention to start the name of a class with
> initial capital, so Te would be a better name.)
>
> To get something into the instance dict, you need to assign it onto the
> instance:
>
> t.x = 42  # puts 'x':42 into t.__dict__
>
> --
> Steven

Hi Steven,

Thanks a lot for your quick and helpful answer!


This would imply that I have to search in the dict of the class and
the dict of the instance. - works nicely.

I wonder if there is somewhere a "merge of the two" already available.

In the meantime, I came across dir()
In [7]: dir(t)
Out[7]: ['__doc__', '__init__', '__module__', 'a', 'b']

This seems to return 'a' and 'b', but now crashes

@property
def attributelist(self):
        # find all attributes to the class that are of type numpy
arrays:
        return [attr for attr in self.__dict__ if
isinstance(getattr(self, attr), numpy.ndarray)]



[toc] | [prev] | [next] | [standalone]


#17340

FromUlrich <ulrich.dorda@gmail.com>
Date2011-12-16 01:14 -0800
Message-ID<08b0a976-dd2a-4728-b865-4d04f4e5b7fb@n10g2000vbg.googlegroups.com>
In reply to#17339
On Dec 16, 10:11 am, Ulrich <ulrich.do...@gmail.com> wrote:
> On Dec 16, 10:03 am, Steven D'Aprano <steve
>
>
>
>
>
>
>
>
>
> +comp.lang.pyt...@pearwood.info> wrote:
> > On Fri, 16 Dec 2011 00:52:11 -0800, Ulrich wrote:
> > > Good morning,
>
> > > I wonder if someone could please help me out with the @property function
> > > as illustrated in the following example.
>
> > > class te():
> > >     def __init__(self):
> > >         self.a = 23
> > >     @property
> > >     def b(self):
> > >         return 2 * self.a
> > [...]
> > > Could anyone please explain me why this does not work / how to get b
> > > into .__dict__ / hint me to an explanation?
>
> > b is a property object. Like any other assignment inside the body of the
> > class, it is shared across all instances, so you won't find it in the
> > instance's personal dict. You will find it in the shared class dict.
>
> > t.__dict__['b']  # not found
> > te.__dict__['b']  # will return the property object
>
> > (By the way: it is the usual convention to start the name of a class with
> > initial capital, so Te would be a better name.)
>
> > To get something into the instance dict, you need to assign it onto the
> > instance:
>
> > t.x = 42  # puts 'x':42 into t.__dict__
>
> > --
> > Steven
>
> Hi Steven,
>
> Thanks a lot for your quick and helpful answer!
>
> This would imply that I have to search in the dict of the class and
> the dict of the instance. - works nicely.
>
> I wonder if there is somewhere a "merge of the two" already available.
>
> In the meantime, I came across dir()
> In [7]: dir(t)
> Out[7]: ['__doc__', '__init__', '__module__', 'a', 'b']
>
> This seems to return 'a' and 'b', but now crashes
>
> @property
> def attributelist(self):
>         # find all attributes to the class that are of type numpy
> arrays:
>         return [attr for attr in self.__dict__ if
> isinstance(getattr(self, attr), numpy.ndarray)]


hi again,

I must have hit the send accidently before finishing.

This attributelist should return me all attributes of type
numpy.ndarry.

if I replace it to
def attributelist(self):
         # find all attributes to the class that are of type numpy
arrays:
         return [attr for attr in dir(self) if
isinstance(getattr(self, attr), numpy.ndarray)]

it crashes going into some kind of endless loop.

Do you happen to have any idea?

thanks again!

cheers,

ulrich

[toc] | [prev] | [next] | [standalone]


#17342

FromPeter Otten <__peter__@web.de>
Date2011-12-16 10:32 +0100
Message-ID<mailman.3719.1324027975.27778.python-list@python.org>
In reply to#17340
Ulrich wrote:

> if I replace it to
> def attributelist(self):
>          # find all attributes to the class that are of type numpy
> arrays:
>          return [attr for attr in dir(self) if
> isinstance(getattr(self, attr), numpy.ndarray)]
> 
> it crashes going into some kind of endless loop.
> 
> Do you happen to have any idea?

dir(self) finds an attribute named "attributelist", getattr(self, 
"attributelist") then tries to calculate the value of that attribute, 
invokes dir(self) which finds an attribute named "attributelist" and so on 
ad infinitum or the stack overflows. Try (untested)

@property
def attributelist(self):
    return [attr for attr in dir(self) if attr != "attributelist" and
            isinstance(getattr(self, attr), numpy.ndarray)]

to avoid the infinite recursion.

[toc] | [prev] | [next] | [standalone]


#17361

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-12-16 09:23 -0700
Message-ID<mailman.3736.1324052667.27778.python-list@python.org>
In reply to#17340
On Fri, Dec 16, 2011 at 2:32 AM, Peter Otten <__peter__@web.de> wrote:
> Ulrich wrote:
>
>> if I replace it to
>> def attributelist(self):
>>          # find all attributes to the class that are of type numpy
>> arrays:
>>          return [attr for attr in dir(self) if
>> isinstance(getattr(self, attr), numpy.ndarray)]
>>
>> it crashes going into some kind of endless loop.
>>
>> Do you happen to have any idea?
>
> dir(self) finds an attribute named "attributelist", getattr(self,
> "attributelist") then tries to calculate the value of that attribute,
> invokes dir(self) which finds an attribute named "attributelist" and so on
> ad infinitum or the stack overflows. Try (untested)
>
> @property
> def attributelist(self):
>    return [attr for attr in dir(self) if attr != "attributelist" and
>            isinstance(getattr(self, attr), numpy.ndarray)]
>
> to avoid the infinite recursion.

Or remove attributelist from the class (it feels more like a generic
function than a class property to me) or make it a method instead of a
property.

[toc] | [prev] | [next] | [standalone]


#17343

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2011-12-16 11:02 +0100
Message-ID<jcf50g$716$1@r03.glglgl.gl>
In reply to#17337
Am 16.12.2011 09:52 schrieb Ulrich:

> Could anyone please explain me why this does not work / how to get b
> into .__dict__ / hint me to an explanation?

b is not a data element of the particular instance, but it lives in the 
class. It is, roughly spoken, a "kind of method", just to be used 
without calling. These things are called "data descriptors" 
(http://docs.python.org/reference/datamodel.html#descriptors).

t.b is internally reflected to te.__dict__['b'].__get__(t, te) in order 
to call the __get__ method of the property object. This is done on every 
call and the value is, in your case, derived from the instance value a.

HTH,

Thomas

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web