这是我的第一个问题,很抱歉...... 我是python和编码的初学者,我想创建一个名为'Map'的类,它将具有以下类变量:
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
如果我将变量放在类之外就可以了。 我做错了什么?
感谢您的帮助。
答案 0 :(得分:7)
来自docs:
名称指的是对象。名称由名称绑定操作引入。程序文本中每次出现的名称都是指在包含该用途的最里面的功能块中建立的该名称的绑定。
块是一段Python程序文本,作为一个单元执行。以下是块:模块,函数体和类定义。交互式输入的每个命令都是一个块。脚本文件(作为解释器的标准输入提供的文件或指定为解释器的命令行参数的文件)是代码块。脚本命令(在解释器命令行上使用'-c'选项指定的命令)是代码块。传递给内置函数eval()和exec()的字符串参数是一个代码块。
代码块在执行帧中执行。一个框架包含一些管理信息(用于调试),并确定在代码块执行完成后继续执行的位置和方式。
范围定义块中名称的可见性。如果在块中定义了局部变量,则其范围包括该块。如果定义发生在功能块中,则作用域将扩展到定义块中包含的任何块,除非包含的块为名称引入了不同的绑定。 类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块 - 这包括了解和生成器表达式,因为它们是使用函数作用域实现的。这意味着以下内容将失败:
class A:
a = 42
b = list(a + i for i in range(10))
python3中的list comps有自己的作用域,而不是python2,你的代码可以按原样运行。
如果您使用python2进行以下示例,您可以看到泄漏list comp范围的变量如何导致一些问题:
class A:
a = 42
b = [a for a in range(10)]
a = A()
print(a.a)
9
您有几个选项,可以使用__init__
创建实例属性:
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)
使用方法:
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())
您选择的内容实际上取决于您想要做什么。
答案 1 :(得分:0)
你需要使用b.width和b.height来引用成员变量define。 有关访问成员变量的一些说明,请参阅此帖子 - Accessing a class' member variables in Python?