Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python类变量赋值的不规则性_Python_Initialization - Fatal编程技术网

Python类变量赋值的不规则性

Python类变量赋值的不规则性,python,initialization,Python,Initialization,我试图创建一个具有多个类级别变量的类,其中一些具有引用以前声明的类级别变量的计算值。然而,在某些点上,我很难引用变量 我的第一次尝试: #/usr/bin/env python 从十进制输入十进制 输入数学 类Foo(对象): NUM_bucket=10 桶大小=十进制(1.0个/个桶) BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(BUCKET_SIZE*i*100)) 打印Foo.BUCKET_标签 结果:

我试图创建一个具有多个类级别变量的类,其中一些具有引用以前声明的类级别变量的计算值。然而,在某些点上,我很难引用变量

我的第一次尝试:

#/usr/bin/env python
从十进制输入十进制
输入数学
类Foo(对象):
NUM_bucket=10
桶大小=十进制(1.0个/个桶)
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(BUCKET_SIZE*i*100))
打印Foo.BUCKET_标签
结果:

>python test.py
回溯(最近一次呼叫最后一次):
文件“test.py”,第5行,在
类Foo(对象):
文件“test.py”,第8行,在Foo中
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(BUCKET_SIZE*i*100))
文件“test.py”,第8行,在
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(BUCKET_SIZE*i*100))
NameError:未定义全局名称“BUCKET\u SIZE”
尝试通过类名访问类变量也不起作用:

#/usr/bin/env python
从十进制输入十进制
输入数学
类Foo(对象):
NUM_bucket=10
桶大小=十进制(1.0个/个桶)
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(Foo.BUCKET_SIZE*i*100))
打印Foo.BUCKET_标签
结果:

>python test2.py
回溯(最近一次呼叫最后一次):
文件“test2.py”,第5行,在
类Foo(对象):
文件“test2.py”,第8行,在Foo中
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(Foo.BUCKET_SIZE*i*100))
文件“test2.py”,第8行,在
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(Foo.BUCKET_SIZE*i*100))
NameError:未定义全局名称“Foo”
用硬编码值替换对BUCKET_SIZE的引用修复了该问题;即使在同一行中还有另一个类级变量引用,它也可以正常工作:

#/usr/bin/env python
从十进制输入十进制
输入数学
类Foo(对象):
NUM_bucket=10
桶大小=十进制(1.0个/个桶)
BUCKET_LABELS=tuple(“BUCKET_{}”。xrange(1,NUM_BUCKET+1)中i的格式(int(十进制(0.1)*i*100))
打印Foo.BUCKET_标签
结果:

>python test3.py
(“桶10”、“桶20”、“桶30”、“桶40”、“桶50”、“桶60”、“桶70”、“桶80”、“桶90”、“桶100”)

有人知道在那个地方引用桶大小的正确方法吗?这是Python本身的一个bug吗?(我正在运行Python 2.7.5,顺便说一句)

首先,一个解决方案,只需编辑这一行(注意括号):


现在,如果您想知道为什么它在Python中是这样工作的,为什么它不是一个bug。。。嗯,这不是一件容易的事:-):

[i*2代表xrange中的i(3)]
是一个列表理解。它生成一个实际的列表,可以像这样使用,例如:

>>> a = [i*2 for i in xrange(3)]
>>> a
[0, 2, 4]
(i*2表示xrange(3)中的i))
是一个生成器表达式。它的工作方式非常相似,但并不完全相同,因为它不生成列表或元组,而是生成一个生成器:

>>> a = (i*2 for i in xrange(3))
>>> a
<generator object <genexpr> at 0x02CEE058>
>>> a.next()
0
>>> a.next()
2
>>> a.next()
4
>>> a.next()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
StopIteration
>>> a = (i*2 for i in xrange(3))
>>> tuple(a)
(0, 2, 4)
>>> tuple(a)
()
特别是,当您要求生成器从中生成元组时,生成器实际上根本不知道
Foo.BUCKET\u SIZE
变量(生成器在其范围内工作,与列表相反)。这就是为什么会出现这个错误

因此,一个解决方案是简单地使用列表理解(这更容易处理/更直观)

注:
Decimal()
函数可能不会像您认为的那样:

>>> NUM_BUCKETS = 10
>>> print Decimal(1.0 / NUM_BUCKETS)
0.1000000000000000055511151231257827021181583404541015625
>>> print round(1.0 / NUM_BUCKETS, 2)
0.1

PPS:如果您对
xrange(1,NUM_bucket+1)
部分感到好奇,那么您没有得到错误的原因是因为它是在生成器生成之前计算的,因此,该类变量实际上被生成器的值替换了。。。这看起来像是生成器表达式作用域的问题,因为当我将其更改为列表理解时,错误消失了。此外,NUM_BUCKET在生成器中运行良好,只在BUCKET_size的部分中出现问题本质上是一个重复,除了Python 3上的问题和使用列表理解之外。我没有看到任何好的使用genexps的受骗者。@Laurent:我被纠正了,注释被删除了。你建议的修复在Python 3上中断了。一般来说,最好不要在类语句中使用genexps或理解!这很有效。(另外,我知道十进制除法是错误的。最新版本将其更改为
decimal(1)/NUM_bucket
,效果与预期一样。)
BUCKET_LABELS = tuple("BUCKET_{}".format(int(BUCKET_SIZE * i * 100)) for i in xrange(1, NUM_BUCKETS + 1))
>>> NUM_BUCKETS = 10
>>> print Decimal(1.0 / NUM_BUCKETS)
0.1000000000000000055511151231257827021181583404541015625
>>> print round(1.0 / NUM_BUCKETS, 2)
0.1