python的爬虫都有什么内置函数

更新时间:02-10 教程 由 南鸢 分享

函数

一.引言

a)概念:函数是完成指定或者特定任务的一组代码。在面向对象编程的类中函数通常被称为方法。不同的函数在程序中会扮演不同的角色完成不同的功能。

b)作用:

i.函数的使用可以提高代码的复用性,省去重复代码的编写,提升程序代码重复利用率。

ii.函数能封装内部的实现,保护内部的数据。通常,我们可以将函数看做成一个“黑盒子”。往往函数的使用者并不是函数的编写者,函数的使用者并不需要对函数内部实现和行为进行考虑,可以将精力更多投入到自身业务逻辑的设计中。只有函数的编写者才需要考虑函数内部的实现细节,如何暴露对外的接口,返回什么样的数据值,也就是API的设计。

iii.提高程序的可读性。使得程序模块化。从一盘散散沙变成整齐队列。

iv.提高程序的可维护性。案例:打印一个不同字符组成的分隔符。

二.函数基础

a)可以将函数抽象成现实生活中的工具。工具需要先制作出来才可以使用。函数也是一样的需要先进行函数的定义,然后方可进行函数调用。

b)函数定义语法结构:

def函数名(参数):

#内部代码

return表达式

c)Return:return不是必须要写的,如果需要则写,不需要可不写。Return后面什么都不跟表示returnNone。一旦函数执行过程中遇到了return语句,那么函数中return后面的所有语句将不会执行,函数执行结束。

d)函数调用:

i.语法结构:函数名(参数值)

ii.注意事项:

1.参数之前使用逗号隔开

2.由于python动态语言的特点,函数调用时填写的参数,python不会对参数类型进行检查,如果函数调用中的参数不符合函数内部运行机制的话,会报错。

e)参数:现实函数和调用者之间的交互

i.函数-》工具:使用ATM取钱时需要传入密码数据。

ii.实参和形参的概念。

iii.函数调用时,实参会传值给形参

1.注意:

a)Python的函数参数传递实际上传递的是实参的地址

b)Python中的参数类型分为可变数据类型和不可变数据类型。

2.Test:使用可变数据类型和不可变数据类型的数据作为参数

a=1

deffunc(a):

print("在函数内部修改之前,变量a的内存地址为:%s"%id(a))

a=2

print("在函数内部修改之后,变量a的内存地址为:%s"%id(a))

print("函数内部的a为:%s"%a)

print("调用函数之前,变量a的内存地址为:%s"%id(a))

func(a)

print("函数外部的a为:%s"%a)

打印结果为:

调用函数之前,变量a的内存地址为:1401140288

在函数内部修改之前,变量a的内存地址为:1401140288

在函数内部修改之后,变量a的内存地址为:1401140320

函数内部的a为:2

函数外部的a为:1

解释:作为参数,a被传入函数时,将数字对象1的地址传递给了函数内部的a。执行第一句内部代码时,此时内部的a和外面的a其实是一个东西,因此打印出了同样的内存地址。而当a=2被执行后,由于整数是不可变的数据类型,所以创建了一个新的内部变量a,并赋值2,将数字对象2的内存地址赋给变量a。我们知道,首先,赋值语句具有创建新变量的功能。

刚才说的是不可变类型参数,如果是可变类型的,比如列表呢?

a=[1,2,3]

deffunc(b):

print("在函数内部修改之前,变量b的内存地址为:%s"%id(b))

b.append(4)

print("在函数内部修改之后,变量b的内存地址为:%s"%id(b))

print("函数内部的b为:%s"%b)

print("调用函数之前,变量a的内存地址为:%s"%id(a))

func(a)

print("函数外部的a为:%s"%a)

执行结果是:

调用函数之前,变量a的内存地址为:34875720

在函数内部修改之前,变量b的内存地址为:34875720

在函数内部修改之后,变量b的内存地址为:34875720

函数内部的b为:[1,2,3,4]

函数外部的a为:[1,2,3,4]

三.参数类型:python函数的参数定义灵活度很大,可以定义位置参数,默认参数,动态参数,关键字参数等。

a)位置参数

i.概念:也叫做必传参数,在函数调用时必须明确提供的参数,切参数顺序个数必须和形参保持一致。但是如果在函数调用的时候给实参指定参数名,那么位置参数的顺序可以不同。

b)默认参数:如果给某个参数提供一个默认值,该参数就是默认参数。在函数调用时,可以给默认参数传递一个值,也可以使用默认值。

i.Test:

defpower(x,n=2):

returnx**n

ret1=power(10)#使用默认的参数值n=2

ret2=power(10,4)#将4传给n,实际计算10**4的值

ii.使用默认参数的注意事项:

1.默认参数必须在顺序参数后面

2.默认参数尽量指向不变的对象

a)Test:

下面是国内某上市互联网公司Python面试真题:

deffunc(a=[]):

a.append("A")

returna

print(func())

print(func())

print(func())

不要上机测试,仅凭代码,你能说出打印的结果吗?

很多同学可能会说,这还不简单,肯定是下面的结果啊:

['A']

['A']

['A']

真的是这样吗?错了!真正的结果是:

['A']

['A','A']

['A','A','A']

Why?为什么会这样?

因为Python函数体在被读入内存的时候,默认参数a指向的空列表对象就会被创建,并放在内存里了。因为默认参数a本身也是一个变量,保存了指向对象[]的地址。每次调用该函数,往a指向的列表里添加一个A。a没有变,始终保存的是指向列表的地址,变的是列表内的数据!我们可以测试一下:

deffunc(a=[]):

print("函数内部a的地址为:%s"%id(a))

a.append("A")

returna

b=func()

print('此时b的值为:%s'%b)

print("函数外部b的地址为:%s"%id(b))

print("-------------")

c=func()

print('此时c的值为:%s'%c)

print("函数外部c的地址为:%s"%id(c))

print("-------------")

d=func()

print('此时d的值为:%s'%d)

print("函数外部d的地址为:%s"%id(d))

打印结果是:

函数内部a的地址为:39287880

此时b的值为:['A']

函数外部b的地址为:39287880

-------------

函数内部a的地址为:39287880

此时c的值为:['A','A']

函数外部c的地址为:39287880

-------------

函数内部a的地址为:39287880

此时d的值为:['A','A','A']

函数外部d的地址为:39287880

那么如何避免这个问题呢?

使用不可变的数据类型作为默认值!

deffunc(a=None):

#注意下面的if语句

ifaisNone:

a=[]

a.append("A")

returna

print(func())

print(func())

print(func())

将默认参数a设置为一个类似None,数字或字符串之类的不可变对象。在函数内部,将它转换为可变的类型,比如空列表。这样一来,不管调用多少次,运行结果都是['A']了。

iii.动态参数

1.概念:函数调用时传入的参数可以是动态数量的,可以为任意个,甚至是0个。

2.分类:重点是*的个数,*后的名字任意。动态参数必须放在所有位置参数和动态参数后面。

a)*args:可以接受任意个参数。调用时,会将实参打包成一个元组传给形参。如果参数是一个列表,则会将整个列表当做一个参数传入。

i.Test

deffunc(*args):

forarginargs:

print(arg)

func('a','b','c')

li=[1,2,3]

func(li)

ii.上述案例中,我们本意是将li这个列表中的元素作为参数进行传值,但是实际却是将列表本身作为一个整体进行了传递。如果想要将一个序列类型的对象(元组,列表,字符串,字典)的元素依次作为参数进行传递,则可以在序列对象前加一个*即可。如果参数是字典,则会将字典所有的key逐一传递进去。

1.Test:

deffunc(*args):

forarginargs:

print(arg)

li=[1,2,3]

func(*li)

b)**kwargs:表示接受键值对的动态参数,数量任意。调用时,会将参数打包成一个字典。

i.Test:

deffunc(**kwargs):

forkwginkwargs:

print(kwg,kwargs[kwg])

print(type(kwg))

func(k1='v1',k2=[0,1,2])

运行结果是:

k1v1

k2[0,1,2]

ii.而如果我们这样传递一个字典dic呢?我们希望字典内的键值对能够像上面一样被逐一传入。

1.Test:

deffunc(**kwargs):

forkwginkwargs:

print(kwg,kwargs[kwg])

dic={

'k1':'v1',

'k2':'v2'

}

func(**dic)

iv.关键字参数:关键字参数前面需要一个特殊分隔符*和位置参数及默认参数分隔开来。*后面的参数被视为关键字参数。在函数调用时,关键字参数必须传入参数名。

1.Test:

defstudent(name,age,*,sex):

pass

student(name="jack",age=18,sex='male')

Test2:如果函数定义中已经有了一个*args参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了。

defstudent(name,age=10,*args,sex,classroom,**kwargs):

pass

student(name="jack",age=18,sex='male',classroom="202",k1="v1")

总结:参数定义顺序:位置参数,动态参数,关键字参数,动态参数

声明:关于《python的爬虫都有什么内置函数》以上内容仅供参考,若您的权利被侵害,请联系13825271@qq.com
本文网址:http://www.25820.com/tutorial/14_2166101.html