今天,我再次被多年后可变的默认参数所困扰。除非需要,否则我通常不会使用可变的默认参数,但我想随着时间的推移,我忘记了这一点。今天在应用程序中,我在PDF生成函数的参数列表中添加了tocElements=[],现在在每次调用"generate pdf“之后,”目录“变得越来越长。:)
我还应该在我的清单中添加什么必须避免的东西?
from y import x
和import x
都是treated as different modules.range()
无论如何都会变成迭代器,以下代码将失败:myIndexList = 0,1,3 isListSorted = myIndexList == range(3) #将在3.0中失败isListSorted = myIndexList == list(range(3)) #不会
同样的事情也可以错误地用xrange来完成:
myIndexList == xrange(3)
尝试:提高KeyError("hmm bug"),KeyError除外,TypeError:打印TypeError
这将打印"hmm bug",尽管它不是一个bug;看起来我们正在捕获这两种类型的异常,但是我们只将KeyError作为变量TypeError来捕获,请使用以下代码:
尝试:提高错误(“hmm KeyError”),除非(KeyError,TypeError):print TypeError
发布于 2009-08-24 08:17:26
不要使用索引在序列上循环
不要:
for i in range(len(tab)) :
print tab[i]
执行以下操作:
for elem in tab :
print elem
For将为您自动执行大多数迭代操作。
如果确实需要索引和元素,请使用enumerate
。
for i, elem in enumerate(tab):
print i, elem
使用"==“检查 True 或 False时要小心
if (var == True) :
# this will execute if var is True or 1, 1.0, 1L
if (var != True) :
# this will execute if var is neither True nor 1
if (var == False) :
# this will execute if var is False or 0 (or 0.0, 0L, 0j)
if (var == None) :
# only execute if var is None
if var :
# execute if var is a non-empty string/list/dictionary/tuple, non-0, etc
if not var :
# execute if var is "", {}, [], (), 0, None, etc.
if var is True :
# only execute if var is boolean True, not 1
if var is False :
# only execute if var is boolean False, not 0
if var is None :
# same as var == None
如果可以,请不要检查,只需执行此操作并处理错误
Pythonistas通常会说“请求宽恕比请求许可更容易”。
不要:
if os.path.isfile(file_path) :
file = open(file_path)
else :
# do something
执行以下操作:
try :
file = open(file_path)
except OSError as e:
# do something
或者使用python 2.6+ /3做得更好:
with open(file_path) as file :
它更好,因为它更具通用性。你可以将"try / except“应用到几乎任何东西上。你不需要关心做什么来防止它,只需要关心你冒着错误的风险。
不检查类型
Python是动态类型的,因此检查类型会使您失去灵活性。取而代之的是,通过检查行为来使用鸭子类型。例如,您希望在函数中包含字符串,然后使用str()将字符串中的任何对象转换为字符串。你需要一个列表,使用list()来转换列表中的任何可迭代对象。
不要:
def foo(name) :
if isinstance(name, str) :
print name.lower()
def bar(listing) :
if isinstance(listing, list) :
listing.extend((1, 2, 3))
return ", ".join(listing)
执行以下操作:
def foo(name) :
print str(name).lower()
def bar(listing) :
l = list(listing)
l.extend((1, 2, 3))
return ", ".join(l)
使用最后一种方法,foo将接受任何对象。Bar将接受字符串、元组、集合、列表等。廉价干货:-)
不要混用空格和制表符
别哭了。你会哭的。
使用 object 作为第一个父
这很棘手,但随着程序的增长,它会咬你一口。Python 2.x中有旧的和新的类。旧的是,好吧,旧的。它们缺少一些功能,而且继承起来可能会有笨拙的行为。为了可用,你的任何一个类都必须是“新风格”的。为此,让它继承自"object“:
不要:
class Father :
pass
class Child(Father) :
pass
执行以下操作:
class Father(object) :
pass
class Child(Father) :
pass
在Python3.x中,所有的类都是新的风格,所以你可以声明class Father:
是好的。
不要在 __init__
方法之外初始化类属性
来自其他语言的人发现它很诱人,因为这就是您在Java或PHP中所做的工作。您编写类名,然后列出您的属性并给它们一个默认值。它似乎在Python中工作,然而,这并不是你想的那样工作。
这样做将设置类属性(静态属性),然后当您尝试获取对象属性时,它会给出它的值,除非它为空。在这种情况下,它将返回类属性。
这意味着两个大的危险:
不要(除非你想要静态的):
class Car(object):
color = "red"
wheels = [wheel(), Wheel(), Wheel(), Wheel()]
执行以下操作:
class Car(object):
def __init__(self):
self.color = "red"
self.wheels = [wheel(), Wheel(), Wheel(), Wheel()]
发布于 2009-06-22 04:27:30
当您需要一组数组时,您可能会想要键入下面这样的内容:
>>> a=[[1,2,3,4,5]]*4
果然,当你看着它时,它会给你你所期望的
>>> from pprint import pprint
>>> pprint(a)
[[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]
但是不要期望你的群体中的元素是独立的对象:
>>> a[0][0] = 2
>>> pprint(a)
[[2, 2, 3, 4, 5],
[2, 2, 3, 4, 5],
[2, 2, 3, 4, 5],
[2, 2, 3, 4, 5]]
除非这是你需要的..。
值得一提的是一种解决方法:
a = [[1,2,3,4,5] for _ in range(4)]
发布于 2009-06-18 10:24:09
Python语言Gotchas --以非常隐蔽的方式失败的东西
使用可变的默认arguments.
09
是一个非常隐蔽的语法错误。超类的拼写错误更严重,因为没有一个子类正确地覆盖它。Python设计Gotchas
globals()
。而且,当你打字的时候,几乎所有的东西都是全局的。在适当的程序中,您永远不会“失去对变量的跟踪”,而且没有任何东西是全局的。https://stackoverflow.com/questions/1011431
复制相似问题