函数:带名字的代码块,用于完成具体的工作。
要执行函数定义的任务,可调用该函数。需要在程序中多次执行同一项任务时,无需反复编写完成该任务的代码,而只需调用执行该任务的函数,让Python运行其中的代码。
常用内置函数
类型转换:bool,int,float,str,bytes,tuple,list,dict,set,enumerate,range
序列操作:all,any,filter,map,zip,next,reversed,sorted
对象操作:dir,id,hash,type,len,format
变量操作:globals,locals
交互操作:input,print
文件操作:open
反射操作:isinstance,issubclass,hasattr,getattr,setattr,delattr
装饰器:property,classmethod,staticmethod
def greet_user():
"""显示简单的问候语"""
print('Hello!')
greet_user() # Hello!
在函数定义def greet_user()的括号内添加username,通过添加username,可让函数接收给username指定的任何值。
def greet_user(username):
print("Hello, " + username + "!")
greet_user("jesse") # Hello, jesse!
函数执行过程:
鉴于函数定义中可能包含多个参数,因此函数调用中也可能包含多个实参;
向函数传递参数的方式很多,可使用
位置参数:要求实参的顺序与形参的顺序相同;
关键字参数:每个实参都由变量名和值组成,还可使用列表和字典。
在函数调用时,python必须将函数调用中的每个参数都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置参数。
def describe_pet(animal_type,pet_name):
"""显示宠物的信息"""
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster','harry')
describe_pet('dog','willie')
执行过程:
注:
def describe_pet(animal_type,pet_name):
"""显示宠物的信息"""
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(animal_type='hamster',pet_name='harry')
执行过程:
注:
def describe_pet(pet_name,animal_type):
"""显示宠物的信息"""
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('willie',animal_type='dog')
describe_pet(animal_type='dog','willie') # 报错,SyntaxError: positional argument follows keyword argument
小结:
在实参的角度来看,分为三种:
def describe_pet(pet_name,animal_type='dog'):
"""显示宠物的信息"""
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(pet_name='willie')
执行过程:
注:
def eat(*args):
print('我想吃:',args)
eat('米饭','面条','馄饨') # 收到的结果是一个tuple元组
# 我想吃: ('米饭', '面条', '馄饨')
def eat(*args,a,b):
print('我想吃:',args,a,b)
eat('米饭','面条','馄饨') # TypeError: eat() missing 2 required keyword-only arguments: 'a' and 'b'
若动态参数在前,就会报错,eat函数在调用的时候发现缺少俩个位置参数没有进行传递;原因是动态参数把所有的位置参数都给接受了,所以会报错。
def eat(a,b,*args,c='白菜'):
print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱') # 我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜
执行过程:
注:
小结:
在形参的角度来看,分为三种:
def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3) # 动态关键字参数最后获取的是一个dict字典的形式
# {'a': 1, 'b': 2, 'c': 3}
def func(*args,**kwargs):
print(args,kwargs)
func(1,23,5,a=1,b=6) # (1, 23, 5) {'a': 1, 'b': 6}
def func(*args):
print(args)
lst = [1,2,3,4,5]
func(*lst)
def func2(**kwargs):
print(kwargs)
dic = {
'a':111,'b':222}
func2(**dic)
# 在实参位置上用*将lst(可迭代对象)按照顺序打散
# 在形参位置上用*把接收到的参数组合成一个元组
def func():
print(1111)
return # ret为 None
return 555 # ret为 555
return 555,'asd','fgd' # ret为 (555, 'asd', 'fgd')
print(2222)
ret = func()
print(ret,type(ret))
def func():
a = 80
print(a)
func() # 80
print(a) # NameError: name 'a' is not defined
命名空间:
存放名字和值的关系的空间称为命名空间。变量在存储时,就存储在该空间内。
命名空间分类:
加载顺序:
内置命名空间 > 全局命名空间 > 局部命名空间(函数被执行的时候)
取值顺序:
局部命名空间 > 全局命名空间 > 内置命名空间
a = 20
def func():
a = 80
print(a)
func() # 80 函数内执行局部命名空间中的a=80
print(a) # 20 函数外执行全局命名空间中的a=20
作用域:
作用域就是作用范围,按照生效范围来看分为全局作用域和局部作用域。
a = 20
def func():
a = 80
b = 30
print(a,b)
print('haha')
print(globals())
print(locals())
func()
# 执行结果
80 30
haha
{
'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001DFB012FFD0>, '__spec__': None, '__annotations__': {
}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'c:/Users/Administrator/Desktop/def.py', '__cached__': None, 'a': 20, 'func': <function func at 0x000001DFB00471F0>}
{
'a': 80, 'b': 30}
lambda函数:
lambda表示的是匿名函数,不需要用def来声明,一句话就可以声明出一个函数
语法:
函数名 = lambda 参数:返回值
注意:
1. 函数的参数可以有多个,多个参数之间用逗号隔开;
2. 匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据;
3. 返回值和正常函数一样,可以是任意数据类型,返回值的时候只能返回一个不能返回多个。
def func(n):
return n**n
print(func(4)) # 256
f = lambda x:x**x
print(f(4)) # 256
Python Lambda函数的几种使用方法:
dic = {
'a':4,'b':2,'c':10,'d':6}
print(sorted(dic.items(),key=lambda item: item[0])) # [('a', 4), ('b', 2), ('c', 10), ('d', 6)]
lst = ['1','0','33','45675']
print(sorted(lst,key=lambda s: len(s))) # 根据lst中字符串的长度进行排序 ['1', '0', '33', '45675']
lst2 = [{
'id':1,'name':'alex','age':18},{
'id':2,'name':'wusir','age':17},{
'id':3,'name':'taibai','age':16}]
print(sorted(lst2,key=lambda e: e['age'])) # 根据lst2中的age大小进行排序 [{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}]
lst = [{
'id':1,'name':'alex','age':18},{
'id':2,'name':'wusir','age':17},{
'id':3,'name':'taibai','age':16}]
f = filter(lambda e: e['age']>17,lst)
print(list(f)) # 筛选lst中年龄大于17的元素 [{'id': 1, 'name': 'alex', 'age': 18}]
lst = [1,2,3,4,5]
lst2 = [6,7,8,9,10]
m = map(lambda n: n*n,lst)
print(list(m)) # [1, 4, 9, 16, 25]
m2 = map(lambda x,y: x+y,lst,lst2)
print(list(m2)) # 计算两个列表中相同位置的数据的和 [7, 9, 11, 13, 15]
reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推
from functools import reduce
def func(x,y):
return x+y
lst = [1,2,3,4,5]
print(reduce(func,lst)) # 15 此例子使用sum也可以实现
def func2(x,y):
return x*10+y
ret = reduce(func2,lst)
print(ret)
# 第一次:x=1,y=2,结果12
# 第二次:x=12,y=3,结果123
# 第三次:x=123,y=4,结果1234
# 第四次:x=1234,y=5,结果12345
内置函数:
python提供的可以直接拿来用的函数。截至python3.9.1,python一共提供了69个内置函数。为了方便记忆和查询,将这些内置函数进行如下分类:
print(abs(-10)) # 10
print(divmod(15,2)) # (7,1)
print(max([2,4,3,8])) # 8
print(min([2,4,3,8])) # 2
print(sum([2,4,3,8])) # 17
print(pow(2,3)) # 8
print(pow(2,3,6)) # 2
print(round(12.3356,2)) # 12.34
print(bool()) # False
print(bool(0)) # False
print(bool(1)) # True
print(int()) # 0
print(int(3.6)) # 3
print(float()) # 0.0
print(float(3)) # 3.0
print(float('3')) # 3.0
print(complex()) # 0j 当两个参数都不提供时,返回复数 0j
print(complex('1+2j')) # (1+2j) 传入字符串创建复数
print(complex(3,4)) # (3+4j) 传入数值创建复数
print(str()) # ''
print(str(None)) # None
print(str(123)) # '123'
print(bytearray('中文','utf-8')) # bytearray(b'\xe4\xb8\xad\xe6\x96\x87')
print(bytes('中文','utf-8')) # b'\xe4\xb8\xad\xe6\x96\x87'
v = memoryview(b'abcdefg')
print(v[0]) # 97
print(v[1]) # 98
print(v[-1]) # 103
# 补充
s1 = '中国'
bs1 = bytes(s1,encoding='utf-8')
print(bs1) # b'\xe4\xb8\xad\xe6\x96\x87' 字符串转字节
bs2 = str(bs1,encoding='utf-8')
print(bs2) # 中国 将字节转换成字符串
s2 = '你好'
bs3 = s2.encode('utf-8')
print(bs3) # b'\xe4\xbd\xa0\xe5\xa5\xbd' 以指定的编码格式编码字符串,此处为utf-8,返回编码后的字符串
bs4 = bs3.decode('utf-8')
print(bs4) # 你好 以指定的编码格式解码字符串,此处为utf-8,返回解码后的字符串
print(ord('a')) # 97
print(chr(97)) # a
print(bin(10)) # 0b1010
print(oct(10)) # 0o12
print(hex(10)) # 0xa
print(tuple()) # () 不传入参数,创建空元组
print(tuple('123')) # ('1', '2', '3') 传入可迭代对象。使用其元素创建新的元组
print(list()) # [] 不传入参数,创建空列表
print(list('1234')) # ['1', '2', '3', '4'] 传入可迭代对象,使用其元素创建新的列表
print(dict()) # {} 不传入任何参数时,返回空字典
print(dict(a = 1,b = 2)) # {'a': 1, 'b': 2} 可以传入键值对创建字典
print(dict((('a',1),('b',2)))) # {'a': 1, 'b': 2} 可以传入可迭代对象创建字典
print(dict(zip(['a','b'],[11 ,22]))) # {'a': 11, 'b': 22} 可以传入映射函数创建字典
print(set()) # set() 不传入参数,创建空集合
print(set(range(10))) # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 传入可迭代对象,创建集合
print(frozenset(range(10))) # frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
lst = ['a','b','c']
for i,k in enumerate(lst):
print('序号:', i ,'元素:', k) # 序号: 0 元素: a ;序号: 1 元素: b;序号: 2 元素: c
print(range(10)) # range(0, 10)
print(list(range(10))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in range(10):
print(i) # 0,1,2,3,4,5,6,7,8,9
a = iter('ab')
print(next(a)) # a
print(next(a)) # b
print(next(a)) # 没有元素,停止迭代,后面的代码不执行 StopIteration
s1 = slice(1,5,2) # 定义步长和范围,开始idx=1,结束idx=2,步长为2,注意区间是左闭右开
str = 'abcdefg'
print(s1) # slice(1, 5, 2)
print(str[s1]) # bd 使用定义好的s1进行切片
class A:
def add(self,x):
y = x + 1
print('aaa')
print(y)
class B(A):
def add(self,x):
print('bbb')
super().add(x)
b = B()
b.add(3) # bbb aaa 4
a = object()
print(a) #
print(type(a)) #
# 元素全不为 0,'',False,则all()返回True
print(all(['a','b','','c'])) # False 列表list,存在一个为空的元素
print(all((0,1,2,3))) # False 元组tuple,存在一个为0的元素
print(all([])) # True 空列表
print(all(())) # True 空元组
# 元素不都为0,'',False,则any()返回True
print(any([0,'',{
}])) # False 列表list,元素全为0,'',False
print(any((0,1,2,3))) # True 元组tuple,元素不全为0,'',False
print(any([])) # False 空列表
print(any(())) # False 空元组
# filter(function, iterable), iterable可迭代对象;python2.7返回列表,python3.x返回迭代器对象
print(filter(lambda x:x%2==1, range(10))) #
print(list(filter(lambda x:x%2==1, range(10)))) # [1, 3, 5, 7, 9]
# map(function, iterable, ...), iterable一个或多个序列;python2.x返回列表,python3.x返回迭代器对象
print(map(lambda x: x**2,range(6))) #
print(list(map(lambda x: x**2,range(6)))) # [0, 1, 4, 9, 16, 25]
print(list(map(lambda x,y: x+y,[1,2,3,4,5],[6,7,8,9,10]))) # [7, 9, 11, 13, 15]
# zip([iterable, ...]), iterable一个或多个迭代器;python2.x返回列表,python3.x返回一个对象,如需展示列表,需手动list()转换
print(zip([1,2,3],[4,5,6])) #
print(list(zip([1,2,3],[4,5,6]))) # [(1, 4), (2, 5), (3, 6)]
print(dict(zip([1,2,3],[4,5,6]))) # {1: 4, 2: 5, 3: 6}
# next(iterable[, default]) iterable可迭代对象,next() 函数要和生成迭代器的 iter() 函数一起使用
it = iter([2,4,6,8,10])
while True:
try:
x = next(it) # 获取下一个值
print(x) # 2 4 6 8 10
except StopIteration: # 遇到StopIteration就退出循环
break
# reversed(seq) seq可以是列表,元组,字符串以及range()生成的区间列表
print([x for x in reversed(range(10))]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print([y for y in reversed('abcdefg')]) # ['g', 'f', 'e', 'd', 'c', 'b', 'a']
# sorted(iterable,key=None,reverse=False) iterable可迭代对象,reverse是否倒序,默认正序,reverse=False
# key排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数,根据函数的运算的结果进行排序
a = [5,7,6,3,4,1,2]
b = sorted(a)
print(b) # [1, 2, 3, 4, 5, 6, 7]
print(a) # [5, 7, 6, 3, 4, 1, 2] 保留原函数
c = [('b',2),('a',1),('c',3),('d',4)]
print(sorted(c,key=lambda x: x[1])) # [('a', 1), ('b', 2), ('c', 3), ('d', 4)] 根据c中的下标为1的元素进行排序
d = {
'c':3,'b':6,'a':8,'d':4}
print(sorted(d.items(),key=lambda item: item[0])) # [('a', 8), ('b', 6), ('c', 3), ('d', 4)]
print(sorted(d.items(),key=lambda item: item[1])) # [('c', 3), ('d', 4), ('b', 6), ('a', 8)]
lst = [1,2,8,7,6,4]
lst.sort()
print(lst)
# 补充:
sort和sorted区别:
1.sort是应用在list上的方法,sorted可以对所有可迭代的对象进行排序操作;
2.list的sort方法返回的是对已经存在的列表进行操作,无返回值;而内置函数sorted返回的是一个新的list,而不是在原来的基础上进行的操作。
import sys
print(help(sys)) # 查看 sys 模块的帮助
print(help(str)) # 查看 str 数据类型的帮助
print(help([1,2,3])) # 查看列表 list 帮助信息
print(help([1,2,3].append)) # 显示list的append方法的帮助
print(dir([])) # 查看列表的方法
print(dir(())) # 查看元组的方法
print(id('python')) # 1991000924720
print(hash('python')) # -5052387211587165361
print(type(1)) #
print(type('python')) #
print(type([2])) #
print(type({
1:'aaa'})) #
print(len('python')) # 6
print(len([1,2,3])) # 3
print(ascii(1)) # 1
print(ascii('#')) # '#'
print(ascii('中文')) # '\u4e2d\u6587'
print(vars())
class A:
a = 111
def is_odd(n):
return n % 2 == 1
print(vars(A))
# {'__module__': '__main__', 'a': 111, 'is_odd': , '__dict__': , '__weakref__': , '__doc__': None}
print('{} {}'.format('hello','world')) # hello world 不设置指定位置,按默认顺序
print('{0} {1}'.format('hello','world')) # hello world 设置指定位置
print('{0} {1} {0}'.format('hello','world')) # hello world hello 设置指定位置
print('网站:{name}, 地址:{url}'.format(name='百度',url='www.baidu.com')) # 网站:百度, 地址:www.baidu.com
# 通过字典设置参数
site = {
"name": "百度", "url": "www.baidu.com"}
print('网站:{name}, 地址:{url}'.format(**site)) # 网站:百度, 地址:www.baidu.com
# 通过列表索引设置参数
site_list = ["百度", "www.baidu.com",["google","www.google.com"]] # "0" 是必须的
print('网站:{0[0]}, 地址:{0[1]}'.format(site_list)) # 网站:百度, 地址:www.baidu.com
print('网站:{0[2][0]}, 地址:{0[2][1]}'.format(site_list)) # 网站:google, 地址:www.google.com
# 数字格式化
print('{:.2f}'.format(3.141592653)) # 3.14 保留小数点后两位
print('{:.0f}'.format(3.141592653)) # 3 不带小数
print('{:.2%}'.format(3.141592653)) # 314.16%
print('{:.2%}'.format(0.25)) # 25.00%
print(globals())
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000019A7084FFD0>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'c:/Users/Administrator/Desktop/def.py', '__cached__': None}
def func(n):
print('before define m')
print(locals()) # {'n': 2}
m = 10
print('after define m')
print(locals()) # {'n': 2, 'm': 10}
func(2)
print(globals())
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000019A7084FFD0>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'c:/Users/Administrator/Desktop/def.py', '__cached__': None, 'func': }
# print(*objects,sep='',end='\n',file=sys.stdout,flush=False) objects表示可以输出多个对象,输出多个对象时,用‘,’分割;sep用来间隔多个对象,默认值是一个空格;end用来设定以什么结尾,默认是换行符\n,可换成其它字符串;file要写入的文件对象;flush输出是否被缓存通常取决于file,但如果flush关键字参数为True,流会被强制刷新
print('aaaa''bbbb') # aaaabbbb
print('www','baidu','com',sep='.') # www.baidu.com 设置间隔符
print(111,222,end='\taaa') # 111 222 aaa 设置结尾字符串,空格\t,默认换行符\n
# input([prompt]) prompt提示信息
a = input('请输入:')
print(a) # 123
print(type(a)) #
# python3里input()默认接收到的是str类型
# open(file,mode,buffering,encoding,)
# file表示要打开的文件路径;mode可选字符串,用于指定打开文件的模式,默认值‘r’;encoding用于解码或编码文件的编码的名称(应该只是在文本模式下使用),默认依赖于平台的编码
# buffering可选整数,0切换缓冲关闭(仅在二进制模式下),1选择行缓冲(仅在文本模式下可用),>1的整数以指定固定大小的块缓冲区的大小(以字节为单位)
在python中,字符串\有转义的含义,直接使用程序不会被识别
f = open('C:\Users\Administrator\Desktop\text.txt','r',buffering=1,encoding='utf-8')
解决方式(绝对路径):
1.在路径前面加r,即保持字符原始值的意思
f = open(r'C:\Users\Administrator\Desktop\text.txt','r',buffering=1,encoding='utf-8')
2.替换为双反斜杠
f = open('C:\\Users\\Administrator\\Desktop\\text.txt','r',buffering=1,encoding='utf-8')
3.替换为正斜杠
f = open('C:/Users/Administrator/Desktop/text.txt','r',buffering=1,encoding='utf-8')
相对路径:
f = open(r'text.txt','r',buffering=1,encoding='utf-8')
print(f.read())
f.close()
相对路径:同一个文件夹下面的文件,直接写文件名就可以
绝对路径:从根目录下开始一直到文件名
# eval(expression[, globals[, locals]]) expression表达式
n = 8
print(eval('2+n')) # 10
def func():
return 666
print(eval('func()')) # 666
# exec 执行字符串类型的代码
msg = '''
def plan():
print('有计划没行动等于0')
plan()
'''
exec(msg) # 有计划没行动等于0
# repr返回一个对象的string形式
s = 'python'
print(repr(s)) # 'python'
dict = {
'baidu': 'baidu.com', 'google': 'google.com'}
print(repr(dict)) # {'baidu': 'baidu.com', 'google': 'google.com'}
# compile 返回表达式执行结果
s = 'for i in range(0,3): print(i)'
t = compile(s,'','exec')
exec(t)
# 0
# 1
# 2
s2 = '2*4+6'
t2 = compile(s2,'','eval')
print(eval(t2)) # 14
# isinstance(object,classinfo) object实例对象,classinfo可以是直接或间接类名,数据类型或者由他们组成的元组
print(isinstance(2,int)) # True
print(isinstance(2,str)) # False
print(isinstance(2,(int,str,list))) # True
class A:
pass
class B(A):
pass
class C:
pass
print(isinstance(A(),A)) # True
print(type(A()) == A) # True
print(isinstance(B(),A)) # True
print(type(B()) == A) # False
# 补充
isinstance和type的区别:
1.isinstance()会认为子类是一种父类类型,考虑继承关系;
2.type()不会认为子类是一种父类类型,不考虑继承关系。
# issubclass(class, classinfo) 判断参数 class 是否是类型参数 classinfo 的子类
print(issubclass(B,A)) # True
print(issubclass(B,(A,C))) # True
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
s = Student('Aim',10)
print(hasattr(s,'name')) # True
print(hasattr(s,'age')) # False
print(hasattr(s,'gender')) # False
print(getattr(s,'name')) # Aim
print(getattr(s,'age')) # 10
print(getattr(s,'gender','male')) # male 不存在属性gender,但提供了默认值,返回默认值
print(getattr(s,'gender')) # 不存在属性gender,未提供默认值,调用报错 AttributeError: 'Student' object has no attribute 'gender'
setattr(s,'gender','female')
setattr(s,'phone','123456')
print(getattr(s,'gender')) # female
print(getattr(s,'phone')) # 123456
delattr(s,'gender')
print(getattr(s,'gender')) # AttributeError: 'Student' object has no attribute 'gender'
# 对于函数、方法、lambda函数、类以及实现了__call__方法的类实例,callable()都返回True
def func():
return 0
print(callable(func)) # True
class Foo():
def __init__(self,name):
self.name = name
f = Foo('Aim')
print(callable(Foo)) # True
print(callable(f)) # False
class Foo2():
def __init__(self,name):
self.name = name
def __call__(self):
return 1
f2 = Foo2('Aim')
print(callable(Foo2)) # True
print(callable(f2)) # True