《pyhton基础教程》第六章整理

时间:2021-09-24 18:47:35
·内建的callable函数可以用来判断函数是否可以调用
>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True

在python3中不可再用,使用表达式hasattr(func,__call__)

·文档化函数

在def语句后面以及阿紫模块或者类的开头,如果在函数的开头写下字符串,它就会作为函数的一部分进行存储,这称为文档字符串

>>> def square(x):
'Calculates the square of the number x.'
return x*x

#获得文档字符串的两种方式
>>> square.__doc__ #__doc__是函数属性,双下滑线表示它是特殊属性
'Calculates the square of the number x.'
>>> help(square)
Help on function square in module __main__:

square(x)
Calculates the square of the number x.

·所有的函数都返回了东西,当不需要他们返回值时就返回None

>>> def test():
return

>>> x = test()
>>> x
>>> print x
None

参数调用时可变参数与不可变参数的区别

  • 当参数为不可变的时(即无法被修改,只能用新的值覆盖,如字符串,数字,元组),在函数内赋予变量新值不会改变参数的值
>>> def try_to_change(n):
n = 'Mr.Gumby'


>>> name = 'Mrs.Entity'
>>> try_to_change(name)
>>> name
'Mrs.Entity'

其具体的工作方式:

>>> name = 'Mrs.Entity'
>>> n = name
>>> n = 'Mr.Gumby'
>>> name
'Mrs.Entity'
  • 当参数为可变的时,修改形参的值会改变实参的值
>>> names = ['Mr.Entity','Mrs.Thing']
>>> change(names)
>>> names
['Mr.Gumby', 'Mrs.Thing']

具体的工作方式:

>>> names = ['Mr.Entity','Mrs.Thing']
>>> n = names
>>> n[0] = 'Mr.Gumby'
>>> names
['Mr.Gumby', 'Mrs.Thing']

如果不想可变参数被改变,可以复制一个列表的副本,再调用函数

>>> names = ['Mr.Entity','Mrs.Thing']
>>> n = names[:] #序列做切片时返回的总是一个副本
>>> n is names #此时调用change(n)并不会改变names
False
>>> n == names
True

但如果想让不可变参数通过函数来改变值呢?没有办法,通常的做法应该是这样

>>> foo = 10
>>> foo = inc(foo)
>>> foo
11

如果真想改变参数,可以将值放置在列表中

>>> def inc(x):
x[0] = x[0] + 1


>>> foo = [10]
>>> inc(foo)
>>> foo
[11]

位置参数与关键字参数

位置参数:

位置参数一般都是一个单词 ,如:
  函数声明 def a(x,y) 中的x,y
  函数调用时的a(p,q)
对于位置参数,变量的位置比名字重要(形参和实参的名字可以不一样,但位置要对应上)

关键字参数:

关键字参数一般是一个键值对 ,如:
  函数声明 def b(x=1,y=2)
  调用函数时 b(x=2,y=4)
关键字参数在函数声明中的使用主要用于设置参数的默认值,设置了默认值的参数可以不用再传入

  位置参数与关键字参数是可以联合使用的,把位置参数放在前面就可以了,创建函数和调用函数都是这样

>>> def a(x=2,y,z=1):     #创建函数时把关键字参数写在位置参数前
return
SyntaxError: non-default argument follows default argument
>>> def a(x,y,z=2):    
return

>>> a(z=2,1,2) #调用函数时把关键字参数写在了未致参数前
SyntaxError: non-keyword arg after keyword arg

这种写法不报错>>> a(z=2,x=1,y=2),因为这些全是关键字参数

收集参数及其逆用

  收集参数可以将任意数量的参数收集起来,有两种:
第一种

将位置参数收集成元组的形式

>>> def print_params(*params):
print params


>> print_params()
()
>> print_params(1)
(1,)
>> print_params(1,2,3)
(1, 2, 3)

当然,有‘固定位置’的位置参数优先给到自己对应位置的参数上

>>> def print_params(x,y=1,*params):
print x,y
print params


>>> print_params(0)
0 1
()
>> print_params(0,3)
0 3
()
>> print_params(0,3,4,)
0 3
(4,)
>> print_params(0,3,4,5,6)
0 3
(4, 5, 6)

总的来说,星号的意思就是“**收集多余的位置参数”,
换句话说,在定义函数时,这种带星号的参数得写在普通的参数后面

>>> def print_params(*params,x=1):
print params

SyntaxError: invalid syntax
>>> SyntaxError: invalid syntax
>>> def print_params(*params,x):
print params

SyntaxError: invalid syntax

第二种

将关键字参数收集成字典的形式

>>> def print_params(**keypar):
print keypar


>> print_params()
{}
>> print_params(x=1,y=2,z='aa')
{'y': 2, 'x': 1, 'z': 'aa'}

这种是将剩余的关键字参数收集成字典的形式,但是不用在意‘已有’关键字参数与‘其余’关键字参数的顺序

>>> def print_params(x=1,y=2,**keypar):
print x,y
print keypar


>> print_params(z=4,x=3,q=5)
3 2
{'q': 5, 'z': 4}

收集参数的逆用根据字面上就知道,是将元组或字典打开变成参数的形式

>>> def hello(name,greeting):
print name,',',greeting,'!'


>>> params=('nairoj','hello')
>>> hello(*params)
nairoj , hello !

作用域

  变量和所对应的值可以看成存储在一个看不见的字典内,用 vars()函数可以返回这个字典

>>> vars()
{'__builtins__': <module '__builtin__' (built-in)>, '__doc__': None, 'params': ('nairoj', 'hello'), '__name__': '__main__', '__package__': None, 'hello': <function hello at 0x0345DA30>}

而这个看不见的字典就是作用域,当函数调用时,就会创建一个新的作用域

>>> def create_x():
x=1
print vars()


>>> create_x()
{'x': 1}

与vars函数类似的有获取全局变量值的globals()和获取局部变量值的locals()

>>> def create_x():
x=1
print vars()
print locals()
print globals()


>>> create_x ()
{'x': 1}
{'x': 1}
{'create_x': <function create_x at 0x0345DE30>, '__builtins__': <module '__builtin__' (built-in)>, '__doc__': None, 'params': ('nairoj', 'hello'), '__name__': '__main__', '__package__': None, 'hello': <function hello at 0x0345DA30>}

由上程序可知在函数内是可以获取到函数外的全局变量值的,实际上在函数内是可以直接访问全局变量的

>>> y = 1
>>> def create_x():
x=1
print x,y


>>> create_x ()
1 1

但是试图直接修改是不行的,之前也说过

>>> y = 1
>>> def create():
x=1
y=2 #会被看成在局部作用域内创建变量
print x,y


>>> create ()
1 2
>>> y
1

  那如果想在函数内修改全局变量呢?两种方法:
第一种

之前提到的globals()函数返回的是全局的“字典”,那么我直接对这个字典进行修改就可以了

>>> y=1
>>> def change():
y=2
globals()['y']=3


>>> change()
>>> y
3

第二种

使用关键字global

>>> y = 1
>> def change():
global y #声明y是全局变量,global y=2 是不被允许的
y = 2


>> change()
>> y
2