Python-全局变量和局部变量&函数&递归&深浅拷贝
1.全局变量和局部变量
money = 10 # 全局变量
def func():
num = 'num' # 局部变量
global money
money += 500
print(num + money)
'''
global money # 在局部变量中想修改全局变量,需要用global声明你要修改的是全局变量
全局列表、字典、集合在修改时,不用声明全局变量,可以直接修改
全局int、str、tuple(元组)在修改时,需要先声明为全局变量
即可变类型的全局变量在修改时,不用声明全局变量,可以直接修改;不可变类型,需要声明(元组元素不能修改)
'''
2.函数定义
def test1(): # 定义一个函数
pass # 表示没有函数体,直接过
def test2(a, b): # 定义一个有参的函数
return a # 函数返回值
3.函数参数
# 1、必填参数(位置参数)
def say_word(word):
print(word)
# 2、默认值参数:可以不传参数,不传参数的时候使用默认值,传了参数时使用所传参数
# (使用默认值参数可以实现一个函数实现多个功能,例如一个函数实现读和写两个功能)
def say_hello(word='hello'): # 默认值参数
print(word)
# 3、参数组(可变参数):不限制参数的类型和数量
def send_mail(*args): # 此时args是元组类型,名称可改(例如:*name),习惯上使用args
for name in args:
print('给%s发邮件' % name)
return args
send_mail()
send_mail('zhangsan')
send_mail('zhangsan', 'lisi', 'wangwu')
# 4、关键字传参:形参较多时,可以使用关键字传参,参数可以不用按照顺序传参
'''
调用参数时,可以全部使用位置参数,位置一一对应,必须按照位置传参
也可以全部使用关键字传参,指定关键字,就不需要按照顺序传参
也可以位置参数和关键字参数一起使用,但要先写位置参数在用关键字参数,关键字参数后面不能再使用位置参数
'''
def szz(name, age, sex, addr, phone):
print('111')
szz(sex='man', name='zhangsan', addr='beijing', age=18, phone='13565243526') # 使用关键字参数
szz('zhangsan', 18, sex='man', addr='beijing', phone='13565243526') # 位置参数和关键字参数混合使用
# 如下,是否传参不限制,参数类型和数量不限制,但是只能使用关键字参数,不能使用位置参数
def name(**kwargs): # 关键字传参,此时kwargs是字典类型,名称可改(例如:**name),习惯上使用kwargs
print(kwargs)
name()
name(name='zhangsan', age='18', phone='1234')
name(name='zhangsan', age='18', phone='1234', addr='beijing')
# 指定参数类型
def add_user(username: str, passwd: int): # 指定传入参数类型,传入参数时,也可以不传入指定类型
username.strip()
print(passwd)
# 参数练习1:
def student(name, age=None, *args, **kwargs):
print(name) # 位置参数
print(age) # 默认参数
print(args) # 参数组
print(kwargs) # 关键字参数
student('zhangsan', 18, 'lisi', 'wangwu', sex='man', phone='123')
# 参数练习2:
def db_mysql(host, port, user, passwd, db):
print(host)
print(port)
print(user)
print(passwd)
print(db)
db_info1 = ('127.0.0.1', 3306, 'root', '1234567', 'szz')
db_info2 = {
'host': '127.0.0.1',
'port': 3306,
'user': 'root',
'passwd': '1234567',
'db': 'szz',
}
db_mysql(*db_info1)
db_mysql(**db_info2)
# * 代表拆开db_info1(解包),将db_info1中的元素与参数意义对应,但db_info1中的元素不能多于参数数量,且位置需与参数位置对应
# db_info1只要是有下标的数据类型即可,例如列表,元组,字符串等
# ** 代表拆开db_info2字典(解包),将db_info2中的元素与参数意义对应,但db_info2中的元素不能多于参数数量,且key的位置需与参数位置对应
4.函数返回值
# return的作用:1.返回函数值 2.结束函数
# 返回多个值,用一个变量接收,那么会将多个返回值放入一个元组中进行返回
def get_file(age, name, addr):
age += 5
name = 'szz' + name
addr = 'beijing' + addr
return age, name, addr
res = get_file(19, 'xiaohei', 'chaoyang') # 多个返回值使用一个变量接收
age, name, addr = get_file(19, 'xiaohei', 'chaoyang') # 多个返回值使用多个变量接收
print(res) # 打印出的会是一个元组
5.递归
# 递归:函数自己调用自己,最大次数调用999次
def say():
num = input('请输入一个数字:').strip()
if int(num) % 2 != 0:
print('请输入一个偶数')
say()
say()
# 练习:
li = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in li:
if i % 2 != 0:
li.remove(i)
print(li) # 结果为:[1, 2, 4, 6, 8]
# 原因是,循环删除列表元素时,再次循环,列表元素会更新
# 解决方法如下:
l1 = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l2 = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 不能写成l2=l1,因为变量存储时是存的内存地址,l2=l1时,l1和l2内存地址相同
# 写法2:l2 = l1[:]
for i in l2:
if i % 2 != 0:
l1.remove(i)
print(l1)
print(id(l1))
print(id(l2)) # 查看内存地址
6.深拷贝和浅拷贝
# 深拷贝
l1 = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l2 = l1[:] # 开辟了新的内存空间,两个变量之间互不影响
# 浅拷贝
l2 = l1 # 未开辟新的内存空间,两个变量之间会被互相影响
# 深拷贝和浅拷贝的区别,浅拷贝不会开辟新的内存空间,深拷贝会开辟新的内存空间
import copy # 导入copy模块
d = {'name': 'zhangsan', 'age': [12, 1, 14]}
d1 = d # 浅拷贝
d2 = copy.deepcopy(d) # 深拷贝函数
d3 = copy.copy(d) # 浅拷贝,但是d和d3的内存地址不同,但若d中存在多层(例如列表元素),则不会拷贝深层的内容
7.内置函数
input() # 输入
tuple() # 元组
bool # 布尔
dict() # 字典
list() # 列表
len() # 求长度
sum([1, 2, 3]) # 求和
max([1, 2, 3]) # 求最大值
min([1, 2, 3]) # 求最小值
round(1.98234, 2) # 取几位小数(将1.98234保留两位小数)
divmod(10, 5) # 取商和余数
globals() # 用于全局时,取当前文件中的所有变量;用于局部时,依然取当前文件的所有变量
locals() # 用于全局时,取当前文件中的所有变量;用于局部时,取局部的所有变量
chr(55) # 将ascii转成对应的字符
ord('A') # 将字符转成对应的ascii
dir(d) # 查看d中有哪些方法
# 排序
sorted(l) # 对l进行排序,l可以是list、字符串等,排序后会返回一个list,升序
sorted(l, reverse=True) # 降序排序
# 执行python代码
code = '''
print('1')
'''
exec(code) # 运行python代码
eval(code) # 执行简单的python代码
# 枚举 enumerate
l = [1, 2, 3, 4, 5]
for id, i in enumerate(l, 1): # 将l列表中的元素从1开始,自动编号
print('%s=>%s' % (id, i))
# 压缩
zip() # 压缩,将多个列表合在一起;不限制于列表,对字典使用时,只合并两个字典的key值;若一列表元素多余另一元素,则以少的为准
list1 = ['xiaoming', 'xiaobai', 'xiaohei', 'zhangsan']
list2 = [1, 2, 3, 4, 5]
l1 = {'name': 1, 'age': 2}
l2 = {'add': 3, 'phone': 4}
res = list(zip(l1, l2))
res1 = list(zip(list1, list2))
print(res)
print(res1)
# 循环调用
import os
list(map(os.mkdir, ['1', '2', '3']))
# 循环调用函数,获取函数返回结果;表示循环列表中的值调用os.mkdir函数,注意函数不加括号,后面只要是可以循环的即可
# map(os.mkdir,['1','2','3'])直接这样写不会调用即不会真的执行,需强转
score = [89, 43, 60, 52, 45, 37, 66, 100, 21, 24]
def is_jg(s):
if s > 59:
return True
result = list(filter(is_jg, score))
# 循环调用函数,将返回True的保存,否则过滤