Python开发

python进阶教程,python爬虫实例教程

Python进阶中文教程

我仔细学习了该进阶教程,原著根据《Intermediate Python》译注,学习了之后我再例子以及重点地方多做了一些标注。

args 和 *kwargs*args 的用法**kwargs 的用法使用 args 和 *kwargs 来调用函数啥时候使用它们调试 Debugging生成器 Generators可迭代对象(Iterable)迭代器(Iterator)迭代(Iteration)生成器(Generators)Map,Filter 和 ReduceMapFilterReduceset 数据结构三元运算符装饰器一切皆对象在函数中定义函数从函数中返回函数将函数作为参数传给另一个函数你的第一个装饰器使用场景授权日志带参数的装饰器在函数中嵌入装饰器装饰器类Global和Return多个return值对象变动 Mutationslots魔法虚拟环境容器 Collections枚举 Enumerate对象自省dirtype和idinspect模块推导式 Comprehension列表推导式字典推导式集合推导式异常处理多个异常finally从句try/else从句lambda表达式一行式For – Elseelse语句使用C扩展CTypesSWIGPython/C APIopen函数目标Python2+3协程函数缓存Python 3.2+Python 2+上下文管理器基于类的实现处理异常基于生成器的实现译者在翻译过程中,慢慢发现,本书作者的行文方式有着科普作家的风范,–那就是能将晦涩难懂的技术用比较清晰简洁的方式进行呈现,深入浅出的风格在每个章节的讨论中都得到了体现:

*args 和 **kwargs 我观察到,大部分新的Python程序员都需要花上大量时间理解清楚 *args 和**kwargs这两个魔法变量。那么它们到底是什么?

首先让我告诉你, 其实并不是必须写成*args 和**kwargs。 只有变量前面的 *(星号)才是必须的. 你也可以写成*var 和**vars. 而写成*args 和**kwargs只是一个通俗的命名约定。 那就让我们先看一下*args吧。

*args 的用法 *args 和 **kwargs 主要用于函数定义。 你可以将不定数量的参数传递给一个函数。

这里的不定的意思是:预先并不知道, 函数使用者会传递多少个参数给你, 所以在这个场景下使用这两个关键字。 *args 是用来发送一个非键值对的可变数量的参数列表给一个函数.

这里有个例子帮你理解这个概念:

def test_var_args(f_arg, *argv):print “first normal arg:”, f_argfor arg in argv:print “another arg through *argv:”, argtest_var_args(‘yasoob’, ‘python’, ‘eggs’, ‘test’) 这会产生如下输出:

first normal arg: yasoobanother arg through *argv: pythonanother arg through *argv: eggsanother arg through *argv: test 我希望这解决了你所有的困惑. 那接下来让我们谈谈 **kwargs

**kwargs 的用法 **kwargs 允许你将不定长度的键值对, 作为参数传递给一个函数。 如果你想要在一个函数里处理带名字的参数, 你应该使用**kwargs。

这里有个让你上手的例子:

def greet_me(**kwargs):for key, value in kwargs.items():print “{0} == {1}”.format(key, value)greet_me(name=”yasoob”)这会产生如下输出:name == yasoob 现在你可以看出我们怎样在一个函数里, 处理了一个键值对参数了。

这就是**kwargs的基础, 而且你可以看出它有多么管用。 接下来让我们谈谈,你怎样使用*args 和 **kwargs来调用一个参数为列表或者字典的函数。

那现在我们将看到怎样使用*args和**kwargs 来调用一个函数。 假设,你有这样一个小函数:

def test_args_kwargs(arg1, arg2, arg3):

print(“arg1:”, arg1)

print(“arg2:”, arg2)

print(“arg3:”, arg3)

你可以使用*args或**kwargs来给这个小函数传递参数。 下面是怎样做:

# 首先使用 *args

>>> args = (“two”, 3, 5)

>>> test_args_kwargs(*args)

# 现在使用 **kwargs:

>>> kwargs = {“arg3”: 3, “arg2”: “two”, “arg1”: 5}

>>> test_args_kwargs(**kwargs)

标准参数与*args、**kwargs在使用时的顺序 那么如果你想在函数里同时使用所有这三种参数, 顺序是这样的:

some_func(fargs, *args, **kwargs) 什么时候使用它们? 这还真的要看你的需求而定。

最常见的用例是在写函数装饰器的时候(会在另一章里讨论)。

此外它也可以用来做猴子补丁(monkey patching)。猴子补丁的意思是在程序运行时(runtime)修改某些代码。 打个比方,你有一个类,里面有个叫get_info的函数会调用一个API并返回相应的数据。如果我们想测试它,可以把API调用替换成一些测试数据。例如:

import someclassdef get_info(self, *args):return “Test data”someclass.get_info = get_info 我敢肯定你也可以想象到一些其他的用例

生成器(Generators)

首先我们要理解迭代器(iterators)。根据维基百科,迭代器是一个让程序员可以遍历一个容器(特别是列表)的对象。然而,一个迭代器在遍历并读取一个容器的数据元素时,并不会执行一个迭代。你可能有点晕了,那我们来个慢动作。换句话说这里有三个部分:

可迭代对象(Iterable)迭代器(Iterator)迭代(Iteration) 上面这些部分互相联系。我们会先各个击破来讨论他们,然后再讨论生成器(generators).

可迭代对象(Iterable) Python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法(这些双下划线方法会在其他章节中全面解释),那么它就是一个可迭代对象。简单说,可迭代对象就是能提供迭代器的任意对象。那迭代器又是什么呢?

迭代器(Iterator) 任意对象,只要定义了next(Python2) 或者__next__方法,它就是一个迭代器。就这么简单。现在我们来理解迭代(iteration)

迭代(Iteration) 用简单的话讲,它就是从某个地方(比如一个列表)取出一个元素的过程。当我们使用一个循环来遍历某个东西时,这个过程本身就叫迭代。现在既然我们有了这些术语的基本理解,那我们开始理解生成器吧。

生成器(Generators) 生成器也是一种迭代器,但是你只能对其迭代一次。这是因为它们并没有把所有的值存在内存中,而 是在运行时生成值。你通过遍历来使用它们,要么用一个“for”循环,要么将它们传递给任意可以进行迭代的函数和结构。大多数时候生成器是以函数来实现 的。然而,它们并不返回一个值,而是yield(暂且译作“生出”)一个值。这里有个生成器函数的简单例子:

def generator_function():for i in range(10):yield ifor item in generator_function():     print(item)# Output: 0 # 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 这个案例并不是非常实用。生成器最佳应用场景是:你不想同一时间将所有计算出来的大量结果集分配到内存当中,特别是结果集里还包含循环。

译者注:这样做会消耗大量资源

许多Python 2里的标准库函数都会返回列表,而Python 3都修改成了返回生成器,因为生成器占用更少的资源。

下面是一个计算斐波那契数列的生成器:

# generator version def fibon(n):a = b = 1for i in range(n):yield a         a, b = b, a + b 函数使用方法如下:

for x in fibon(1000000):     print(x) 用这种方式,我们可以不用担心它会使用大量资源。然而,之前如果我们这样来实现的话:

Similar Posts

发表评论

邮箱地址不会被公开。 必填项已用*标注