I have the following code:
import numpy as np
class ClassProperty(property):
def __get__(self, cls, owner):
return self.fget.__get__(None, owner)()
def coord(cls, c):
if cls.dimension <= 2:
return c
else:
return c + [0]*(cls.dimension-2)
class Basis_NonI(object):
@ClassProperty
@classmethod
def zerocoord(cls):
return coord(cls, [0,0])
def __init__(self, dimension):
pass
class Basis_D(Basis_NonI):
dimension = 2
proj_matrix = np.array([Basis_D.zerocoord, Basis_D.zerocoord])
def __init__(self, dimension):
super(Basis_D, self).__init__(Basis_D.dimension)
where basically I want dimension
and proj_matrix
to be class attributes of Basis_D
.
When I run it, the following error is given:
proj_matrix = np.array([Basis_D.zerocoord, Basis_D.zerocoord])
NameError: name 'Basis_D' is not defined
--
What I don't understand is that I can use Basis_D.dimension in the init
, so why does it not recongise the name Basis_D
when I use it to define proj_matrix
?
Basis_D gets created once all the statements inside it are executed and reaches the end. You can check that using globals() dictionary.
class
is an executable statement. When the module is first imported (for a given process), all the code at the top-level of theclass
statement is executed, all names defined that way are collected into a dict, then theclass
object is created with this dict, and finally bound to the class name. IOW, at this point:the class has not yet been created nor bound to the name
Basis_D
.Now by the time
__init__
is called, the class has already been created and bound to the module-level nameBasis_D
, so the name can be resolved.FWIW, you shouldn't directly reference
Basis_D
in your methods, buttype(self)
(or evenself
- if a name is not resolved as an instance attribute, it's looked up on the class).Also, why do you insist on using class attributes ? Do you understand that your
project_matrix
array will be shared amongst all instances ofBasis_D
?