在需要之前推迟创建属性 [英] Postpone creation of attributes until needed

查看:58
本文介绍了在需要之前推迟创建属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好


我有一个小问题。我想出了一个解决方案,但是我不知道它是否是a)安全的,b)最优的。


我有一个具有多个属性的类,但由于各种原因,我不能在__init__时为所有属性赋值,因为

值取决于其他链接类的属性可能还没有创建
。我可以肯定的是,当要求任何值为
时,所有其他类都已创建,因此可以计算缺失值。

。 />

首先我将值初始化为None,然后当我需要一个

值时,我会检查它是否为None,如果是,请调用一个方法

会计算所有缺失的值。但是,有一些

属性,所以它很乏味。我正在寻找一个可以在任何情况下工作的触发点

。这就是我想出来的。


>> class A(object):



.... __slots__ =(''x'',''y'',''z'')

.... def __init __(self,x,y):

.... self.x = x

.... self.y = y

.... def __getattr __(自我,姓名):

....打印''getattr'',名字

....如果名字不在自我.__ class __.__ slots__:

....引发AttributeError,名称

.... self.z = self .x * self.y

.... return getattr(self,name)


>> a = A(3,4)
ax



3


>> ay



4


>> az



getattr z

12


>> az



12


>> aq



getattr q

属性错误:q


换句话说,我根本没有声明未知属性。这个

导致__getattr__在任何值被请求时被调用,而__getattr__调用设置

属性和计算的方法值。


我使用__slots__来捕获任何无效的属性,否则我会得到

a''最大递归深度超出''错误。


这样可以,还是有更好的方法?


谢谢


Frank Millman

解决方案

2007年6月11日星期一上午10:24,Frank Millman写道:


大家好


我有一个小问题。我想出了一个解决方案,但是我不知道它是否是a)安全的,b)最优的。


我有一个具有多个属性的类,但由于各种原因,我不能在__init__时为所有属性赋值,因为

值取决于其他链接类的属性可能还没有创建
。我可以肯定的是,当要求任何值为
时,所有其他类都已创建,因此可以计算缺失值。

。 />

首先我将值初始化为None,然后当我需要一个

值时,我会检查它是否为None,如果是,请调用一个方法

会计算所有缺失的值。但是,有一些

属性,所以它很乏味。我正在寻找一个可以在任何情况下工作的触发点

。这就是我想出来的。


> class A(object):



... __slots__ =(''x'',''y'',''z'')

... def __init __(self, x,y):

... self.x = x

... self.y = y

... def __getattr__ (自我,姓名):

...打印''getattr'',名字

...如果名字不在自我.__ class __.__ slots__:

...引发AttributeError,名称

... self.z = self.x * self.y

... return getattr(self,name )


> a = A(3,4)
ax



3


> ay



4


> az



getattr z

12


> az



12


> aq



getattr q

属性错误:q


换句话说,我根本没有声明未知属性。这个

导致__getattr__在任何值被请求时被调用,而__getattr__调用设置

属性和计算的方法值。


我使用__slots__来捕获任何无效的属性,否则我会得到

a''最大递归深度超出''错误。


这样可以,还是有更好的方法?



属性......


@property

def z(self):

返回self.x * self.y


Phil


2007年6月11日星期一02: 24:51 -0700,Frank Millman写道:


大家好


我有一个小问题。我想出了一个解决方案,但是我不知道它是否是a)安全的,b)最优的。


我有一个具有多个属性的类,但由于各种原因,我不能在__init__时为所有属性赋值,因为

值取决于其他链接类的属性可能还没有创建
。我可以肯定的是,当要求任何值为
时,所有其他类都已创建,因此可以计算缺失值。



除非你在一个线程中创建类,而另一个线程启动你的实例,我不明白这是怎么回事

可能。


除非......你在做这样的事情吗?

def MyClass(对象) ):

def __init __(自我):

self.x = Parrot.plumage #class属性类

self.y =灌木丛。叶子

也许你应该强制创建类?


def MyClass(对象):

def __init __(self) :

试试:

Parrot

除了Some_Error_Or_Other:#NameError?

#做一些事来创建Parrot类

通过

self.x = Parrot.plumage

#etc.


起初我将值初始化为None,然后当我需要一个

值时,我会检查它是否为None,如果是,请调用一个方法

将计算所有缺失值。但是,有一些

属性,所以它很乏味。我正在寻找一个可以在任何情况下工作的触发点

。这就是我想出来的。


>>> A类(对象):



... __slots__ =(''x'',''y'',''z'')



通过使用插槽,你告诉Python不要为__dict__保留空间,

这意味着你的类不能动态创建属性。


... def __init __(self,x,y):

... self.x = x

... self。 y = y

... def __getattr __(自我,姓名):

...打印''getattr'',名称

。 ..如果名字不在自我.__ class __.__ slots__:

...引发AttributeError,名称

... self.z = self.x * self.y

...返回getattr(self,name)



[snip]


换句话说,我不是完全消除未知属性。这个

导致__getattr__在任何值被请求时被调用,而__getattr__调用设置

属性和计算的方法值。


我使用__slots__来捕获任何无效的属性,否则我会得到

a''最大递归深度超过''错误。



这是该问题的错误解决方案。为了避免这个问题,

__getattr__应该直接写入自己.__ dict__。


这样可以,还是有一个更好的方法?



在交互式Python提示符下:


help(property)


-

史蒂文


6月11日上午11:47,Phil Thompson< p ... @ riverbankcomputing。 co.uk>

写道:


2007年6月11日星期一上午10:24,Frank Millman写道:


你好所有


我有一个小问题。我想出了一个解决方案,但我不知道它是否是a)安全的,b)最优的。


我有一个具有多个属性的类,但由于各种原因我不能为所有属性赋值
在__init__时间,因为

值取决于其他链接类的属性,这些属性可能还没有创建

。我可以肯定的是,当要求任何值为
时,所有其他类都已创建,因此可以计算缺失值。




属性...


@property

def z(self ):

返回self.x * self.y



在我的简单示例中,我只显示了一个缺少的属性 - ''z'' 。在

现实生活中,我有很多,所以我必须为每个人设置一个

单独的属性定义。


使用我的方法,如果引用了* any *缺少的

属性,则调用__getattr__,这似乎更容易,并且如果我添加其他属性则需要更少的
维护。


另一点 - 每次引用

属性时都会调用属性定义,而__getattr__仅在
$ b $时被调用类属__dict__中不存在b属性,这只发生一次

。因此,我认为我的方法应该稍快一些。


Frank


Hi all

I have a small problem. I have come up with a solution, but I don''t
know if it is a) safe, and b) optimal.

I have a class with a number of attributes, but for various reasons I
cannot assign values to all the attributes at __init__ time, as the
values depend on attributes of other linked classes which may not have
been created yet. I can be sure that by the time any values are
requested, all the other classes have been created, so it is then
possible to compute the missing values.

At first I initialised the values to None, and then when I needed a
value I would check if it was None, and if so, call a method which
would compute all the missing values. However, there are a number of
attributes, so it got tedious. I was looking for one trigger point
that would work in any situation. This is what I came up with.

>>class A(object):

.... __slots__ = (''x'',''y'',''z'')
.... def __init__(self,x,y):
.... self.x = x
.... self.y = y
.... def __getattr__(self,name):
.... print ''getattr'',name
.... if name not in self.__class__.__slots__:
.... raise AttributeError,name
.... self.z = self.x * self.y
.... return getattr(self,name)

>>a = A(3,4)
a.x

3

>>a.y

4

>>a.z

getattr z
12

>>a.z

12

>>a.q

getattr q
Attribute Error: q

In other words, I do not declare the unknown attributes at all. This
causes __getattr__ to be called when any of their values are
requested, and __getattr__ calls the method that sets up the
attributes and computes the values.

I use __slots__ to catch any invalid attributes, otherwise I would get
a ''maximum recursion depth exceeded'' error.

Is this ok, or is there a better way?

Thanks

Frank Millman

解决方案

On Monday 11 June 2007 10:24 am, Frank Millman wrote:

Hi all

I have a small problem. I have come up with a solution, but I don''t
know if it is a) safe, and b) optimal.

I have a class with a number of attributes, but for various reasons I
cannot assign values to all the attributes at __init__ time, as the
values depend on attributes of other linked classes which may not have
been created yet. I can be sure that by the time any values are
requested, all the other classes have been created, so it is then
possible to compute the missing values.

At first I initialised the values to None, and then when I needed a
value I would check if it was None, and if so, call a method which
would compute all the missing values. However, there are a number of
attributes, so it got tedious. I was looking for one trigger point
that would work in any situation. This is what I came up with.

>class A(object):


... __slots__ = (''x'',''y'',''z'')
... def __init__(self,x,y):
... self.x = x
... self.y = y
... def __getattr__(self,name):
... print ''getattr'',name
... if name not in self.__class__.__slots__:
... raise AttributeError,name
... self.z = self.x * self.y
... return getattr(self,name)

>a = A(3,4)
a.x


3

>a.y


4

>a.z


getattr z
12

>a.z


12

>a.q


getattr q
Attribute Error: q

In other words, I do not declare the unknown attributes at all. This
causes __getattr__ to be called when any of their values are
requested, and __getattr__ calls the method that sets up the
attributes and computes the values.

I use __slots__ to catch any invalid attributes, otherwise I would get
a ''maximum recursion depth exceeded'' error.

Is this ok, or is there a better way?

Properties...

@property
def z(self):
return self.x * self.y

Phil


On Mon, 11 Jun 2007 02:24:51 -0700, Frank Millman wrote:

Hi all

I have a small problem. I have come up with a solution, but I don''t
know if it is a) safe, and b) optimal.

I have a class with a number of attributes, but for various reasons I
cannot assign values to all the attributes at __init__ time, as the
values depend on attributes of other linked classes which may not have
been created yet. I can be sure that by the time any values are
requested, all the other classes have been created, so it is then
possible to compute the missing values.

Unless you''re doing something like creating classes in one thread while
another thread initiates your instance, I don''t understand how this is
possible.

Unless... you''re doing something like this?
def MyClass(object):
def __init__(self):
self.x = Parrot.plumage # copy attributes of classes
self.y = Shrubbery.leaves
Maybe you should force the creation of the classes?

def MyClass(object):
def __init__(self):
try:
Parrot
except Some_Error_Or_Other: # NameError?
# do something to create the Parrot class
pass
self.x = Parrot.plumage
# etc.

At first I initialised the values to None, and then when I needed a
value I would check if it was None, and if so, call a method which
would compute all the missing values. However, there are a number of
attributes, so it got tedious. I was looking for one trigger point
that would work in any situation. This is what I came up with.

>>>class A(object):

... __slots__ = (''x'',''y'',''z'')

By using slots, you''re telling Python not to reserve space for a __dict__,
which means that your class cannot create attributes on the fly.

... def __init__(self,x,y):
... self.x = x
... self.y = y
... def __getattr__(self,name):
... print ''getattr'',name
... if name not in self.__class__.__slots__:
... raise AttributeError,name
... self.z = self.x * self.y
... return getattr(self,name)

[snip]

In other words, I do not declare the unknown attributes at all. This
causes __getattr__ to be called when any of their values are
requested, and __getattr__ calls the method that sets up the
attributes and computes the values.

I use __slots__ to catch any invalid attributes, otherwise I would get
a ''maximum recursion depth exceeded'' error.

That''s the wrong solution to that problem. To avoid that problem,
__getattr__ should write directly to self.__dict__.

Is this ok, or is there a better way?

At the interactive Python prompt:

help(property)

--
Steven


On Jun 11, 11:47 am, Phil Thompson <p...@riverbankcomputing.co.uk>
wrote:

On Monday 11 June 2007 10:24 am, Frank Millman wrote:

Hi all

I have a small problem. I have come up with a solution, but I don''t
know if it is a) safe, and b) optimal.

I have a class with a number of attributes, but for various reasons I
cannot assign values to all the attributes at __init__ time, as the
values depend on attributes of other linked classes which may not have
been created yet. I can be sure that by the time any values are
requested, all the other classes have been created, so it is then
possible to compute the missing values.



Properties...

@property
def z(self):
return self.x * self.y

In my simple example I showed only one missing attribute - ''z''. In
real life I have a number of them, so I would have to set up a
separate property definition for each of them.

With my approach, __getattr__ is called if *any* of the missing
attributes are referenced, which seems easier and requires less
maintenance if I add additional attributes.

Another point - the property definition is called every time the
attribute is referenced, whereas __getattr__ is only called if the
attribute does not exist in the class __dict__, and this only happens
once. Therefore I think my approach should be slightly quicker.

Frank


这篇关于在需要之前推迟创建属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆