Postpone creation of attributes until needed
Steven D'Aprano
steve at REMOVE.THIS.cybersource.com.au
Mon Jun 11 06:21:51 EDT 2007
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
More information about the Python-list
mailing list