给Python初学者的一些编程发起
当前位置:以往代写 > Python教程 >给Python初学者的一些编程发起
2019-06-14

给Python初学者的一些编程发起

给Python初学者的一些编程发起

Python是一种很是富有表示力的语言。它为我们提供了一个复杂的尺度库和很多内置模块,辅佐我们快速完成事情。然而,很多人大概会迷失在它提供的成果中,不能充实操作尺度库,太过重视单行剧本,以及误解Python根基布局等。本文是一个关于Python新手大概会陷入的一些陷阱的不完全列表。

1.不知道Python版本

这是一个在StackOverflow上重复呈现的问题。很多人能写出在某个版本上完美事情的代码,但在他们在本身的系统上安装有差异版本的Python。要确保你知道你正在利用的Python版本。

你可以通过下边的代码查察Python版本:

[[email protected]]$ python --version
Python 2.7.10
[[email protected]]$ python --V
Python 2.7.10

上面两种要领都是可以的

2.不利用版本打点器

pyenv是一个极好的打点差异Python版本的东西,但很不幸,它只事情在*nix系统上。在Mac系统上,你可以简朴地通过brew install pyenv安装它,在Linux上,也有一个自动安装措施。

3.着迷于一行措施

很多人热衷于一行措施带来的欢快感。纵然他们的一行办理方案比一个多行办理方案低效,他们也会吹捧。

Python中的一行措施在本质上意味着具有多个表达式的巨大推导。譬喻:

l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]

诚恳讲,我编造了上面的例子。但我看到许多人都写雷同的代码。这样的代码在一个礼拜后就会变得难以领略。假如你想做一些稍微巨大的工作,譬喻按照条件简朴地在一个列表或荟萃中添加一个元素,你大概就会出错误。

单行代码并不是什么成绩,是的,他们大概看起来很机动,但不是什么成绩。想象一下,这就像是你在拂拭房间时把所有的对象都塞进你的衣橱。好的代码应该是清洁的,易于阅读的和高效的。

4.操作错误的方法初始化一个荟萃

这是一个更微妙的问题,大概让你措手不及。荟萃推导很像列表推导。

>>> { n for n in range(10) if n % 2 == 0 }
{0, 8, 2, 4, 6}
>>> type({ n for n in range(10) if n % 2 == 0 })

上面就是荟萃推导的一个例子。荟萃就像列表,也是一个容器。所差异的是,一个荟萃中不能有任何反复的值,并且是无序的。看到荟萃推导人们常常错误地认为{}能初始化一个空荟萃。但其实否则,它初始化一个空字典。

>>> {}
{}
>>> type({})

假如你想初始化一个空荟萃,可以简朴地挪用set()要领。

>>> set()
set()
>>> type(set())

留意一个空集适用set()暗示,可是一个包括一些元素的荟萃就就要用花括号困绕元素来暗示。

>>> s = set()
>>> s
set()
>>> s.add(1)
>>> s
{1}
>>> s.add(2)
>>> s
{1, 2}

这和直觉是相反的,因为你期望雷同于set([1, 2])的一些对象。

5.误解GIL

GIL(全局表明器锁)意味着在Python措施中,任意一个时间点只能有一个线程在运行。这意味着当我们建设一个线程并但愿它并行运行时,它并不会那样。Python表明器实际的事情是在差异的运行线程之间快速举办切换。但这只是对实际产生工作的一个很是简朴的表明,实际环境要巨大的多。有许多种并行运行的实例,譬喻利用本质为C扩展的各类库。但运行Python代码时,大部门时间里它不会并行执行。换句话说,Python中的线程并不像Java或C++中的线程。

很多人会实验为Python辩解,说这些都是真正的线程。这确实是真的,但并不能改变这样一个事实:Python处理惩罚线程的方法和你期望的方法是差异的。Ruby语言也有沟通的环境(Ruby也有一个表明器锁)。

指定的办理方案是利用multiprocessing模块。multiprocessing模块提供Process类,它是一个对fork的很好的包围。然而,fork进程比一个线程的价钱高得多,所以你大概不会每次都能看到机能上的晋升,因为差异的process之间需要做大量的事情来举办彼此协调。

然而,这个问题并不存在于每一个Python的实现版本中。譬喻,Python的一个实现PyPy-stm就试图挣脱GIL(仍未不变)。成立在其他平台,如JVM(Jython)或CLR(IronPython),上的Python实现,也没有GIL的问题。

总之,利用Thread类时要多加小心,你获得的大概不是你想要的。

6.利用旧式类

#p#分页标题#e#

在Python 2中,有两种范例的类,别离为“旧式”类和“新式”类。假如你利用Python 3,那么你默认利用“新式”类。为了确保在Python2中利用“新式”类,你需要让你新建设的每一个类都担任object类,且类不能已担任了内置范例,譬喻int或list。换句话说,你的基类、类假如不担任其他类,就老是需要担任object类。

class MyNewObject(object):
# stuff here

这些“新式”类办理一些老式类的基础缺陷,想要具体相识新式类和旧式类请拜见《python新式类和旧式类区别》《python2中的__new__与__init__,新式类和经典类》。

7.按错误的方法迭代

对付这门语言的新手来说,下边的代码长短经常见的:

for name_index in range(len(names)):
print(names[name_index])

在上边的例子中,没有必需挪用len函数,因为列表迭代实际上要简朴得多:

for name in names:
print(name)

另外,尚有一大堆其他的东西辅佐你简化迭代。譬喻,可以利用zip同时遍历两个列表:

for cat, dog in zip(cats, dogs):
print(cat, dog)

假如你想同时思量列表变量的索引和值,可以利用enumerate:

for index, cat in enumerate(cats):
print(cat, index)

在itertools中也有许多有用的函数供你选择。然而请留意,利用itertools函数并不老是正确的选择。假如itertools中的一个函数为你试图办理的问题提供了一个很是利便的办理步伐,譬喻铺平一个列表或按照给定的列表建设一个其内容的分列,那就用它吧。可是不要仅仅因为你想要它而去适应你代码的一部门。

滥用itertools激发的问题呈现的过于频繁,以至于在StackOverflow上一个德高望重的Python孝敬者已经孝敬他们资料的重要构成部门来办理这些问题。

8.利用可变的默认参数

我多次见到过如下的代码:

def foo(a, b, c=[]):
# append to c
# do some more stuff

永远不要利用可变的默认参数,可以利用如下的代码取代:

def foo(a, b, c=None):
if c is None:
c = []
# append to c
# do some more stuff

与其表明这个问题是什么,不如展示下利用可变默认参数的影响:

>>> def foo(a, b, c=[]):
... c.append(a)
... c.append(b)
... print(c)
...
>>> foo(1, 1)
[1, 1]
>>> foo(1, 1)
[1, 1, 1, 1]
>>> foo(1, 1)
[1, 1, 1, 1, 1, 1]

同一个变量c在函数挪用的每一次都被重复引用。这大概有一些意想不到的效果。

总结

这些只是相对来说刚打仗Python的人大概会碰着的一些问题。然而请留意,大概会碰着的问题远非就这么些。然而另一些缺陷是人们像利用Java或C++一样利用Python,而且试图按他们熟悉的方法利用Python。

    关键字:

在线提交作业