python初学者类变量错误

Python beginner Class variable Error

这是我的第一个问题,对不起…我对python和一般的编码是个初学者,我想创建一个名为"map"的类,该类包含以下类变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Map:
    height = 11  
    width = 21

    top = [['#']*width]
    middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)]
    field = top + middle + top

b = Map()

Shell:
>>> middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)]
    NameError: name 'width' is not defined

如果我把变量放在类之外,它就会工作。我做错什么了??

谢谢你的帮助。


来自文档:

Names refer to objects. Names are introduced by name binding operations. Each occurrence of a name in the program text refers to the binding of that name established in the innermost function block containing the use.

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c‘ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block.

A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail:

1
2
3
class A:
    a = 42
    b = list(a + i for i in range(10))

python3中的列表comp有自己的作用域,而python2中的代码将按原样工作。

如果使用python2以下面的示例为例,可以看到泄漏列表comp范围的变量如何导致一些问题:

1
2
3
4
5
6
7
8
class A:
    a = 42
    b = [a for a in range(10)]

a = A()

print(a.a)
9

您有几个选项,可以使用__init__创建实例属性:

1
2
3
4
5
6
7
8
9
class Map:
    def __init__(self):
        self.height = 11
        self.width = 21
        self.top = [['#']*self.width]
        self.middle = [['#']+[' ']*(self.width-2)+['#'] for i in range(self.height-2)]
        self.field = self.top + self.middle + self.top
m=Map()
print(m.field)

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Map:
    @staticmethod
    def meth():
        height = 11
        width = 21
        top = [['#']*width]
        middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)]
        field = top + middle + top
        return field

b = Map()


print(b.meth())

你的选择实际上取决于你想做什么。


您需要使用b.width和b.height来引用成员变量define。有关访问成员变量的一些解释,请参阅本文-在Python中访问类的成员变量?