【问题标题】:Python beginner Class variable ErrorPython初学者类变量错误
【发布时间】:2023-03-14 02:20:01
【问题描述】:

这是我的第一个问题,很抱歉... 我是 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

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

感谢您的帮助。

【问题讨论】:

  • 你通过classes tutorial了吗?
  • b.width? b.身高?因为你在课堂之外,所以地图。看这篇文章会帮助你更好地理解:stackoverflow.com/questions/68645/…
  • 我正在使用 IDLE,不确定这是否重要,再次感谢您抽出宝贵时间帮助我 (:
  • @Padraic Cunningham 如果我将所有这些变量放在 'def __init__(self):' 下,它可以工作,但我希望它们是类变量,如果我更改 'middle = [['# ']+['']*(width-2)+['#']' 到 '中间 = [['#']+['']*(21-2)+['#']' 它也有效...为什么?
  • @Cookiesforhelp,我添加了一些相关文档的答案

标签: python class python-3.x class-variables


【解决方案1】:

来自docs

名称指的是对象。名称由名称绑定操作引入。程序文本中每次出现的名称都是指在包含使用的最内层功能块中建立的该名称的绑定。

块是作为一个单元执行的一段 Python 程序文本。以下是块:模块、函数体和类定义。每个交互输入的命令都是一个块。脚本文件(作为标准输入提供给解释器或指定为解释器的命令行参数的文件)是一个代码块。脚本命令(在解释器命令行上使用“-c”选项指定的命令)是一个代码块。传递给内置函数 eval() 和 exec() 的字符串参数是一个代码块。

代码块在执行帧中执行。框架包含一些管理信息(用于调试)并确定代码块执行完成后在何处以及如何继续执行。

范围定义名称在块中的可见性。如果在块中定义了局部变量,则其范围包括该块。如果定义出现在功能块中,则范围扩展到包含在定义块中的任何块,除非包含的块为名称引入了不同的绑定。 类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块——这包括理解和生成器表达式,因为它们是使用函数范围实现的。这意味着以下将失败:

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

python3 中的列表组合有自己的范围,而 python2 中的代码可以按原样运行。

如果你用python2做下面的例子,你可以看到变量泄漏列表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())

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

【讨论】:

  • 所以...列表中的“for”循环函数无法访问宽度变量?
  • @Cookiesforhelp,是的,完全正确。
  • 感谢您的时间和链接,但是,python2 示例中的最后一个问题是否变量会丢失“字节数据”变成另一个数字,因为这很奇怪
  • @Cookiesforhelp。名称被反弹到循环中的最后一个值。
  • 哦,好吧,所以即使在 python2 中它也完全忽略了“a = 42”,只是创建了一个新的/或覆盖了“a”。
【解决方案2】:

您需要使用 b.width 和 b.height 来引用成员变量定义。 有关访问成员变量的一些说明,请参阅这篇文章 - Accessing a class' member variables in Python?

【讨论】:

  • 这是错误的,实际上与问题无关,错误发生在实例创建之前
【解决方案3】:

我也是Python初学者

使用 init() 函数定义变量

class Map:
    def __init__(self,height,width,top,middle,field):
        self.height = height
        self.width = width
        self.top = top
        self.middle = middle
        self.field = field

另外,在 YouTube 上观看一些 OOP Python 初学者教程。他们真的很有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2015-07-08
    • 2013-05-19
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多