Python 2.x陷阱和地雷

2024-05-29 04:57:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我的问题的目的是用Python增强我的知识库,更好地了解它,包括了解它的错误和惊喜。为了具体起见,我只对CPython解释器感兴趣。

我正在寻找类似于从我的PHP landmines中学到的东西 一些答案对我来说是众所周知的,但有几个却近乎恐怖。

更新: 显然,有一个或两个人对我提出的问题感到不安,这个问题在堆栈溢出之外已经部分得到了回答。作为某种妥协,这里是网址 http://www.ferg.org/projects/python_gotchas.html

请注意,这里的一个或两个答案已经是从上面提到的网站上写的原始答案。


Tags: 答案目的http知识库堆栈www错误cpython
3条回答

循环和lambdas(或任何闭包):变量由name

funcs = []
for x in range(5):
  funcs.append(lambda: x)

[f() for f in funcs]
# output:
# 4 4 4 4 4

解决方法是创建单独的函数或按名称传递参数:

funcs = []
for x in range(5):
  funcs.append(lambda x=x: x)
[f() for f in funcs]
# output:
# 0 1 2 3 4

您应该知道在Python中如何处理类变量。考虑以下类层次结构:

class AAA(object):
    x = 1

class BBB(AAA):
    pass

class CCC(AAA):
    pass

现在,检查以下代码的输出:

>>> print AAA.x, BBB.x, CCC.x
1 1 1
>>> BBB.x = 2
>>> print AAA.x, BBB.x, CCC.x
1 2 1
>>> AAA.x = 3
>>> print AAA.x, BBB.x, CCC.x
3 2 3

惊讶吗?如果你还记得类变量在内部是作为类对象的字典来处理的,那你就不是这样了。对于读取操作,如果在当前类的字典中找不到变量名,则搜索父类。所以,下面的代码再次出现,但有解释:

# AAA: {'x': 1}, BBB: {}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 1 1
>>> BBB.x = 2
# AAA: {'x': 1}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 2 1
>>> AAA.x = 3
# AAA: {'x': 3}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
3 2 3

在类实例中处理类变量也是如此(将此示例视为上述示例的延续):

>>> a = AAA()
# a: {}, AAA: {'x': 3}
>>> print a.x, AAA.x
3 3
>>> a.x = 4
# a: {'x': 4}, AAA: {'x': 3}
>>> print a.x, AAA.x
4 3

默认参数中的表达式在定义函数时计算,在调用函数时不计算。

示例:考虑将参数默认为当前时间:

>>>import time
>>> def report(when=time.time()):
...     print when
...
>>> report()
1210294387.19
>>> time.sleep(5)
>>> report()
1210294387.19

参数when不变。在定义函数时对其求值。在重新启动应用程序之前不会更改。

策略:如果您将参数默认为None,然后在看到它时执行一些有用的操作,您就不会被它绊倒:

>>> def report(when=None):
...     if when is None:
...         when = time.time()
...     print when
...
>>> report()
1210294762.29
>>> time.sleep(5)
>>> report()
1210294772.23

练习:以确保您理解:为什么会发生这种情况?

>>> def spam(eggs=[]):
...     eggs.append("spam")
...     return eggs
...
>>> spam()
['spam']
>>> spam()
['spam', 'spam']
>>> spam()
['spam', 'spam', 'spam']
>>> spam()
['spam', 'spam', 'spam', 'spam']

相关问题 更多 >

    热门问题