NameError:未在类本身内部定义的类的名称-python

时间:2018-10-19 14:25:21

标签: python class methods attributes

我有以下代码:

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)

我基本上希望dimensionproj_matrix成为Basis_D的类属性。

运行它时,出现以下错误:

  

proj_matrix = np.array([Basis_D.zerocoord,Basis_D.zerocoord])

     

NameError:名称'Basis_D'未定义

-

我不了解我可以在init中使用Basis_D.dimension,所以为什么当我用它来定义Basis_D时却不识别名称proj_matrix

2 个答案:

答案 0 :(得分:2)

class是可执行语句。首次导入模块(对于给定进程)时,将执行class语句顶层的所有代码,将以此方式定义的所有名称收集到dict中,然后收集class使用该字典创建对象,并最终将其绑定到类名。 IOW,此时:

class Basis_D(Basis_NonI):
   dimension = 2
   # HERE
   proj_matrix = np.array([Basis_D.zerocoord, Basis_D.zerocoord])

该类尚未创建,也未绑定到名称Basis_D

现在,在调用__init__时,已经创建了该类并将其绑定到模块级名称Basis_D,因此可以解析该名称。

FWIW,您不应该在方法中直接引用Basis_D,而应直接引用type(self)(甚至是self-如果名称未解析为实例属性,则会查询该名称该课程)。

此外,为什么还要坚持使用类属性?您是否了解project_matrix数组将在Basis_D的所有实例之间共享?

答案 1 :(得分:0)

一旦Basis_D中的所有语句执行完毕并到达末尾,便会创建Basis_D。 您可以使用globals()字典进行检查。

class Basis_D(Basis_NonI):
dimension = 2
print('Basis_D got created?:',bool(globals().get('Basis_D')))
#proj_matrix = np.array([Basis_D.zerocoord, Basis_D.zerocoord])
def __init__(self, dimension):
    super(Basis_D, self).__init__(Basis_D.dimension)

print('Basis_D got created?:',bool(globals().get('Basis_D')))

=================== RESTART: D:/PythonWorkspace/sometry.py ===================
Basis_D got created?: False
Basis_D got created?: True