list as an instance attribute

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Mon Sep 14 10:36:18 CEST 2009


Daniel Santos a écrit :
> Here goes,
> 
> I have a base class that is the following :
> 
> class primitive:

pep08 : class names should be Capitalized.

Also, if you're using Python 2.x, make it:

class Primitive(object):
    #...


> 
> 	def __init__(self):
> 		self.name = ""
> 		self.transforms = []
> 
> 	def copyInternalState(self, sourceObj, copyName):

pep08 : methods, attributes and variables names should be all_lower

> 		return null

s/null/None/g


> 
> 	def copy(self, copyName):
> 
> 		# copy the source object internal state
> 		primitiveCopy = self.copyInternalState(self, copyName)
> 
> 		# copy the transformations
> 		primitiveCopy.transforms = []

If copyInternalState is supposed to return an instance of a 
(well-behaved) subclass of 'primitive' - or any object conforming to the 
(implicit) 'primitive' interface, you shouldn't have to do this.

> 		if self.transforms != []:

An empty list has a false value in a boolean test, so the above test 
would be better written as :

                 if self.transforms:

But anyway, the whole test is plain useless:

for item in []:
    print "you won't see me"


> 			for transf in self.transforms:
> 				primitiveCopy.transforms.append(transf.copy())
> 
> 		return primitiveCopy
> 
> 	# more methods. the ones listed should be enough to get the picture
> 
> And a derived class,
> 
> class CircularCilinder(primitive):
> 
> 
> 	def __init__(self, name):
> 
> 		self.name = name
> 		self.baseCenterVertex = [0, 0, 0]
> 		self.heightVertex = [0, 1, 0]
> 		self.radius = 1

You're not calling the __init__ method of primitive. Your code here 
should be:

         def __init__(self, name):
             super(CircularCilinder, self).__init__(name)
             self.baseCenterVertex = [0, 0, 0]
             self.heightVertex = [0, 1, 0]
             self.radius = 1



> 	def copyInternalState(self, sourceObj, copyName):
> 
> 		copy = CircularCilinder(copyName)
> 
> 		copy.setHeight(self.heightVertex[1])
> 		copy.setRadius(self.radius)

Python is not Java. We have good support for computed properties, so you 
*don't* need explicit getters/setters - just start with a plain 
attribute access, you can always turn it into a computed one latter if 
and when the need arises.


> 		return copy
> 
> 
> I then have a script that creates a CircularCilinder,
> 
> cilinder = CircularCilinder("cilinder")
> cilinderCopy = cilinder.copy("cilinderCopy")
> 
> 
> when I run this script I get the error,
> 
> Traceback (most recent call last):
>   File "./testscript.py", line 26, in <module>
>     cilinderCopy = cilinder.copy("cilinderCopy")
>   File "/cygdrive/d/cg/brlcad_api/trunk/src/ds_brlcad_modeler/api/primitive.py",
>  line 64, in copy
>     if self.transforms != []:
> AttributeError: CircularCilinder instance has no attribute 'transforms'

Indeed - you didn't call the superclass's __init__

> 
> the transforms instance attribute is not known in the derived class. But I
> wanted to avoid adding a self.transforms = [] line to the derived class
> __init__ method.

Should be the same wrt/ the 'name' attribute FWIW.

HTH



More information about the Python-list mailing list