函数(一)
基本定义
一个程序的运行经常性伴随着函数, 所以函数可以理解为一段子程序或者子过程
函数的参数
形参
定义函数时候指定调用函数时候需要传递的参数
实参
调用函数时候传递的参数
位置参数
形参的一种, 实参传递给函数时候,根据形参的位置进行传递
默认参数
形参的一种, 函数在定义时候, 指定形参的值, 函数在调用时候, 如果实参传递了数据就使用实参传递的数据,否则就是用定义时候定义的这个值, 这个值又叫默认值
关键字参数
通过变量赋值的方式对函数进行传参
def Test(x,y)
print(x,y)
Test(x=1, y=2)
非固定参数
形参的一种, *args, **kwargs
*args
实参传递的值就是单列容器打散后的值, 就是直接传值, 最后如果没有参数接收, 就有这个参数接收, 用元组的方式保存, 传值方式和位置参数的传值是一样的
**kwargs
实参传递的值就是双列容器打散后的值, 只有字典才是双列容器, 最后如果没有关键字参数接收, 则全部存入kwargs中, 传值方式和关键字传参一样
def Test(name,*args,**kwargs):
print(name,args,kwargs)
Test('周泽SB','说得对',age=88, sex='not knownd')
函数的返回值和作用域
返回值
函数外部的代码想要获得函数的执行结果,则在函数里面用return语句来定义
- 函数在执行过程中只要遇到return语句, 就会停止执行并返回结果
- 如果未在函数中通过return语句来定义返回值, 则函数默认返回值就是None
- 在函数中return多个值, 在函数外部拿到的时候, 这些值会以一个元组的形式呈现
全局与局部变量
局部变量只能够在函数内部调用
全局变量在程序的任何位置都可以被调用
函数内部在调用变量的时候,先找局部变量,再找全局变量
name='周泽SB' # 全局变量
def Test():
global name # 将变量name作为全局变量(不推荐使用)
name='炮王' # 局部变量
print(name)
print(locals()) # 查看局部变量(函数内的变量)
print(globals()) # 查看全局变量
Test() # 炮王
print(name) # 周泽SB
传递列表,字典产生的现象
函数内如果直接调用全局变量, 则可以调用全局变量的一切的属性和方法
ls = ['周泽SB', '胡鸿鹏SB']
dic = {'name': "周泽SB", 'age': 87, 'hobby': '大保健'}
def Test(ls,dic):
ls.append('罗文SB') # ls是全局变量, 函数内调用全局变量ls并执行它的方法
dic['desc']='为老不尊' # dic是全局变量, 函数内调用全局变量ls并执行它的方法
return ls,dic
return_get=Test(ls,dic)
# 打印的结果一模一样
print(return_get)
print(ls,dic)
嵌套&匿名&高阶
嵌套函数
在函数内定义函数并调用这个函数, 只有在外层函数调用时候, 内层函数才会变得有意义
name='周泽SB'
def Test():
name='炮王'
def inner():
name='周泽被绿了'
print('第三层打印',name)
inner()
print('第二层打印',name)
Test()
print('第一层打印',name)
匿名函数
不需要指定函数的名字
一般不会写太复杂的语法, 能写的最复杂的也只是诸如三元运算符之类
calc_lambda = lambda x, y: x ** y # 定义匿名函数
res_lambda = calc_lambda(2, 3) # 调用匿名函数
print(res_lambda) # 打印匿名函数的返回值
- 上面的功能定义成有名函数
def calc(x, y):
return x ** y
res = calc(2, 3)
print(res)
与map函数配合使用
map函数的用法
map(func, *iterables) --> map object
def calc(x):
return x**2
res=map(calc,[1,2,3,4])
print(list(res))
- 与匿名函数连用
res = map(lambda x: x ** 2, [1, 2, 3, 4])
print(list(res))
- 匿名函数使用三元表达式
res = map(lambda x: x ** 2 if x > 10 else x ** 3, [1, 2, 3, 4,12])
print(list(res))
高阶函数
就是返回一个函数名的函数就叫高阶函数
- 接收一个或多个函数作为输入
- 返回的是输入的一个或多个函数的返回值
def get_abs(num):
return int(str(num).strip('-'))
def add(x,y,func): # 接收函数名作为输入
return func(x)+func(y) # 返回输入的函数的返回值
res=add(-130,-5,get_abs)
print(res)
-
练习 写一个余数计算器
def get_abs(num): return int(str(num).strip('-')) def add(x,y,func): return func(x)%func(y) res=add(-7,-6,get_abs) print(res)
函数的递归
- 必须要有一个明确的结束条件
- 每次递归,问题的规模会越来越小,离结果会越来越近
- 递归效率不高,递归层次过多会导致栈溢出, 会占用更多内存, 影响程序性能,所以python解释器默认加了1000层的递归限制
- 将 100这个数字每次都除以2, 一直到不能除
n = 100
while n > 0:
n = n // 2
print(n)
- 通过函数来实现
def calc(n):
print(n)
if n > 0:
n = n // 2
calc(n)
print(n)
calc(100)
内置函数
abs
取绝对值
bin
返回整数的二进制格式( 将十进制转成二进制 ), 输出结果以0b开头
>>> bin(10)
'0b1010'
>>> bin(100)
'0b1100100'
>>> bin(1000)
'0b1111101000'
hex
返回一个10进制的16进制表示形式, 以0x开头
>>> hex(10)
'0xa'
>>> hex(100)
'0x64'
oct
返回一个10进制的8进制表示形式, 以0o开头
>>> oct(10)
'0o12'
bool
返回一个数据结构是True 或者 False ,
0, None(空字符串, 空集合,空字典,空列表, 空元组)都为False, 其余都为True
>>> bool([])
False
>>> bool('')
False
>>> bool(())
False
>>> bool({})
False
>>> bool(0)
False
>>> bool(None)
False
>>> bool(1)
True
>>> bool('周泽SB')
True
all
可迭代对象中每个元素通过bool函数判断都为True, 最后结果为True, 否则是False
>>> test=[1,2,3,0]
>>> all(test)
False
>>> test2=[1,2,3]
>>> all(test2)
True
any
可迭代对象中每个元素通过bool函数判断只要有一个为True, 最后结果为True, 否则是False
>>> test3=[0,None,'']
>>> any(test3)
False
>>> test4=[1,2,0,None,'']
>>> any(test4)
True
bytearray
将字节变成容器对象, 可以修改数据
>>> str='周泽SB'
>>> a=str.encode('gbk')
>>> a
b'\xd6\xdc\xd4\xf3SB'
>>> b=bytearray(a)
>>> b
bytearray(b'\xd6\xdc\xd4\xf3SB')
>>> b[0]
214
>>> b[1]
220
>>> b[2]
212
>>> b[3]
243
>>> b[4]
83
>>> b[5]
66
>>> b[1]=200
>>> b
bytearray(b'\xd6\xc8\xd4\xf3SB')
>>> b.decode('gbk')
'秩泽SB'
bytes
对字符串进行编码
>>> test='周泽大炮'
>>> byte(test,'gbk')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'byte' is not defined
>>> bytes(test,'gbk')
b'\xd6\xdc\xd4\xf3\xb4\xf3\xc5\xda'
>>> test.encode('gbk')
b'\xd6\xdc\xd4\xf3\xb4\xf3\xc5\xda'
callable
用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。
对于函数、方法、lambda 函式、 类以及实现了 **_call_ **方法的类实例, 它都返回 True。
>>> a=1
>>> callable(a)
False
>>> def add(a,b):
... return a+b
...
>>> callable(add) # # 函数返回 True
True
>>> class A(object):
... def method(self):
... return 0
...
>>> callable(A) # 类返回 True
True
>>> a=A()
>>> callable(a) # 没有实现 __call__, 返回 False
False
>>> class B(object):
... def __call__(self):
... return 0
...
>>> callable(B)
True
>>> b=B()
>>> callable(b) # 实现 __call__, 返回 True
True
chr
返回一个数字对应的ascii字符
>>> chr(65)
'A'
>>> chr(90)
'Z'
>>> chr(97)
'a'
>>> chr(122)
'z'
dict
生成一个空字典
>>> dic=dict()
>>> dic
{}
dir
显示对象的所有的可调用属性
>>> test=[1,2,3]
>>> test.
test.append( test.count( test.insert( test.reverse(
test.clear( test.extend( test.pop( test.sort(
test.copy( test.index( test.remove(
>>> dir(test)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
divmod
返回除法的商和余数
>>> divmod(4,3)
(1, 1)
>>> divmod(10,3)
(3, 1)
enumerate
返回列表的索引和元素
>>> a=['周泽SB','胡鸿鹏SB']
>>> enumerate(a)
<enumerate object at 0x10d6c0f78>
>>> list(enumerate(a))
[(0, '周泽SB'), (1, '胡鸿鹏SB')]
eval
把字符串形式的list,dict,set,tuple 再转换成原有的数据类型
a = ['周泽SB', '胡鸿鹏SB']
f = open('eval_test', 'w', encoding='utf-8')
f.write(str(a))
f.close()
f2 = open('eval_test', 'r', encoding='utf-8')
res = f2.read()
f2.close()
print(type(res)) # <class 'str'>
ls_res = eval(res)
print(type(ls_res)) # <class 'list'>
exec
把字符串格式的代码,进行转义并执行
>>> exec("print('周泽SB')")
周泽SB
filter
def Test(x):
return x > 10 # 返回的是True或者False
res = filter(Test, [1, 3, 5, 44, 33])
print(list(res))
# 或者可以用匿名函数
>>> res=filter(lambda x:x>10,[1,44,22,3])
>>> list(res)
[44, 22]
frozenset
把一个集合变成不可修改的数据类型
>>> a={1,2}
>>> a.add(4)
>>> a
{1, 2, 4}
>>> b=frozenset(a)
>>> b.add(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'
>>> b
frozenset({1, 2, 4})
globals
打印全局作用域里所有变量的信息
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'test': [1, 2, 3], 'test2': [1, 2, 3], 'test3': [0, None, ''], 'test4': [1, 2, 0, None, ''], 'str': '周泽SB', 'a': {1, 2, 4, 6}, 'b': frozenset({1, 2, 4}), 'add': <function add at 0x10d6b3a60>, 'A': <class '__main__.A'>, 'B': <class '__main__.B'>, 'dic': {}, 'res': <filter object at 0x10d6b1f60>}
id
查看对象的内存地址
>>> a
{1, 2, 4, 6}
>>> id(a)
4518231624
isinstance
判断一个数据结构的类型
>>> b
frozenset({1, 2, 4})
>>> isinstance(b,frozenset)
True
>>> isinstance(b,list)
False
map
会根据提供的函数对指定序列做映射
>>> map(lambda x:x**2,[2,3,4])
<map object at 0x10d6b1e48>
>>> list(map(lambda x:x**2,[2,3,4]))
[4, 9, 16]
max
求最大值
>>> c=[33,545,232,3433]
>>> max(c)
3433
# 字符串比的是unicode中的对应的ascii里的数字的大小
>>> d=['周泽SB','胡鸿鹏SB']
>>> max(d)
'胡鸿鹏SB'
>>> ascii('周泽SB')
"'\\u5468\\u6cfdSB'"
>>> ascii('胡鸿鹏SB')
"'\\u80e1\\u9e3f\\u9e4fSB'"
min
求最小值
>>> d=['周泽SB','胡鸿鹏SB']
>>> min(d)
'周泽SB'
ord
返回ascii字符对应的十进制数
>>> ord('周')
21608
>>> ord('泽')
27901
>>> ord('S')
83
>>> ord('B')
66
>>> ord('胡')
32993
>>> ord('鸿')
40511
>>> ord('鹏')
40527
round
将一个小数四舍五入
>>> round(16.7,1)
16.7
>>> round(16.79,1)
16.8
>>> round(16.79,0)
17.0
zip
可以把2个或多个列表拼成一个列表
>>> a=[1,2,3]
>>> b=['周泽SB','胡鸿鹏SB']
>>> c=[33,44,55]
>>> zip(a,b)
<zip object at 0x10d6b8708>
>>> list(zip(a,b))
[(1, '周泽SB'), (2, '胡鸿鹏SB')]
>>> list(zip(a,b,c))
[(1, '周泽SB', 33), (2, '胡鸿鹏SB', 44)]
名称空间
存放名字的地方, 存放变量名与值这样一个关系的地方
分类
- Locals
函数内部的名称空间, 一般包括函数的局部变量以及形式参数
- enclosing function
在嵌套函数中外部函数的名称空间
- globals
当前的模块空间, 或者全局空间, 在当前py文件的任何一个区域都是有效的
- _builtins_
内置模块空间, python解释器启动就形成的一些名字空间, 通过 print(dir(_builtins_)) 来查看
查找顺序
Locals ---> enclosing function----> globals ---->_builtins_
level = 'L0'
dir = 11
def func():
level = 'L1'
dir = 22
print(level, dir)
def outer():
level = 'L2'
dir = '33'
print(level, dir)
def inner():
level = 'L3'
dir = '44'
print(level, dir)
inner()
outer()
func()