华子目录
函数
def fn():
print('这是我的第一个函数')
print(fn)#函数地址<function fn at 0x0000021BF5ED8280>
#函数名就是地址
参数
位置参数
位置参数就是将对应位置的实参传递给对应位置的形参
注:参数必须一一对应,不能缺,不能多,否则就会报错
def text(a, b, c):
print(a)
print(b)
print(c)
text(1, 2, 3)
默认值参数
在定义函数时,提前给形参赋值。调用函数时可以不传递实参。如果不传递实参,就以默认值参数为准,如果传递实参,就以传递的为准
def text(a, b, c=0):
print(a)
print(b)
print(c)
text(1, 4)
关键字参数
可以不按照形参定义的顺序来传递,而是根据参数名来传递
def text(a, b, c):
print(a)
print(b)
print(c)
text(b=3, a=2, c=1)
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fn(1,2,c=20) # 混合使用关键字参数和位置参数的时候,位置参数必须写在关键字参数的前面
fn(c=20,1,2) # 报错
实参的类型
实参可以传递任意数据类型,包括函数
*args
1.*args可以接收所有的实参,并将这些实参保存在元组中
2.*args可以与其他形参配合使用,但必须放在最后面
def text(a, b, *args):
print(a)
print(b)
print(args)
text(1, 2, 3, 4, 5, 6)
#
1
2
(3, 4, 5, 6)
**kwargs
可以接收所有的关键字参数,并将这些参数保存在字典中,参数名就是字典的键,参数值就是字典的值
def text(a, b, **kwargs):
print(a)
print(b)
print(kwargs)
text(1, 2, c=2, d=4)
#
1
2
{'c': 2, 'd': 4}
注:*args和kwargs同时使用时,*args必须在kwargs的前面
参数解包
传递实参时,也可以在序列类型的参数前添加星号,这样他会自动的将序列中的元素依次作为参数传递
但是注意,序列中元素的个数必须和函数形参的个数一致
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
t = (1,2,3)
# fn(t[0],t[1],t[2])
fn(*t) # 解包
fn(*[3,4,5])
# fn(*[3,4,5,6]) # 报错
# 需要注意的是,字典要满足一个点就是key的名字要和参数对得上
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
d = {"a":10,'b':20,'c':30}
fn(**d)
函数的返回值
return后面可以是任意的值
1.如果仅仅写一个return 或者不写return,则就等价于 return None
2.在函数中return代表函数执行结束,后面的代码不会再执行
fn 和fn()的区别
print(fn) # fn是函数对象,打印fn其实就是在打印函数对象,地址
print(fn()) # fn()是在调用函数,打印fn()其实就是在打印fn()的返回值
全局作用域
正常情况,python拒绝在函数中修改全局变量,但是考虑到特殊情况下的需求,python中如果要修改全局变量,需要提前声明。用global来声明
全局作用域的生命周期:全局作用域在程序执行时创建,在程序执行结束时销毁
所有函数以外的都是全局作用域
只要代码不是在函数里面的都是全局作用域
在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问
a = 1
def fn():
a = 2
print("内部a = ",a)
fn()
print("外部a = ",a)
内部a = 2
外部a = 1
------global 声明变量为全局变量
a = 1
def fn():
global a
a = 2
print("内部a = ",a)
fn()
print("外部a = ",a)
内部a = 2
外部a = 2
函数作用域(局部作用域)
# 使用变量的时候,会优先在当前作用域中寻找该变量,如果有就使用,没有则继续往上一级作用域寻找,如果全局作用域都没有就会报错
def fn1():
a = 20
def fn2():
a = 10
print(a)
fn2()
fn1()
函数的高级用法
1.函数可以被赋值
2.函数可以作为实参,传入另一个函数
3.函数可以作为返回值
4.函数可以作为容器(列表,字典,集合,元组)的元素
匿名函数lambda
如果一个函数只有一个返回值,return后只有一句代码,就可以使用lambda
语法:
lambda 各参数:运算表达式
普通写法:
def fn(x):
return x*x
print(fn(5))
匿名写法:
f = lambda x:x*x #f就相当于函数名
print(f(5))
dirs = [
lambda x, y: (x + 1, y), # 下
lambda x, y: (x - 1, y), # 上
lambda x, y: (x, y + 1), # 右
lambda x, y: (x, y - 1) # 左
]
for dir in dirs:
nextNode = dir(curNode[0], curNode[1])
# lambda表达式返回一个坐标元组,dir相当于函数名
闭包与装饰器
闭包
def f():
x=1
def g():#g函数为闭包函数
print(x)
return g #把g()的作用域返回到f()中,让两者有联系
a = f() #a = f() == g
a() #a() == g()
def r():
x=3
def t():
print(x)
t()
r()
闭包:如果在一个内部函数里面,对在外作用域(但不是全局作用域)的变量进行引用,那么内部函数就会被认为是闭包。
装饰器
在不修改源代码的基础下给函数添加一个新的功能
import time
def foo():
print("foo...")
time.sleep(1) # 休眠程序
def show_time(func):
start = time.time()
func()
end = time.time()
print(f"程序运行了{end - start}秒")
show_time(foo)
import time
def foo():
print("foo...")
def show_time(func):
def inner():
start = time.time()
func()
time.sleep(1) # 休眠程序
end = time.time()
print(f"程序运行了{end - start}秒")
return inner
foo = show_time(foo) # 返回inner函数
foo() # 调用inner函数
语法糖
@
import time
def show_time(func):
def inner():
start = time.time()
func()
time.sleep(1) # 休眠程序
end = time.time()
print(f"程序运行了{end - start}秒")
return inner
@ show_time #foo=show_time(f00)
def foo():
print("foo...")
foo()
import time
def show_time(func):
def inner(a,b):
start = time.time()
func(a,b)
time.sleep(1) # 休眠程序
end = time.time()
print(f"程序运行了{end - start}秒")
return inner
@ show_time
def fn(a,b):
print(a+b)
fn(1,2)
import time
def show_time(func):
def inner(*args,**kwargs):#传参的目的是为了给func提供参数
start = time.time()
func(*args,**kwargs)
time.sleep(1) # 休眠程序
end = time.time()
print(f"程序运行了{end - start}秒")
return inner
@ show_time
def add1(*args,**kwargs): # 计算任意数的和
result = 0
for i in args:
result += i
print(result)
add1(1,2,3,4,5,6,7,8,9)
生成器和迭代器
生成器
g = (x for x in range(1,10)) # g是一个生成器对象
print(next(g))#1
print(next(g))#2
print(next(g))#3
print(next(g))#4
print(next(g))#5
for循环的本质就是在调用反复的调用next()
g = (x for x in range(1,10))
for i in g: #g是可迭代类型, 本质:next(i)
print(i)
生成器的两种实现方式
1,(i for i in range(1,10))
2,yield关键字
def f():
print("hello world")
yield 1
print(f()) #f()是一个生成器对象
g = f()
next(g) # hello world
def f():
print("你好")
yield 1
print("woaini")
yield 2
for i in f(): # next()
print(i)
你好
1
woaini
2
def f():
print("你好")
yield 1
print("woaini")
yield 2
a = f()
# next(a) #你好
# next(a) #woaini
print(next(a))#你好 和 1
print(next(a))#woaini 和 2
for循环in后面跟的是可迭代对象,可迭代对象不是迭代器,生成器是可迭代对象,迭代器也是可迭代对象。
从现象看,只要可以for循环的都是可迭代对象(iterable)
从本质看,是内置有iter方法的是可迭代对象
for循环本质:能循环是因为内部有iter方法
可迭代对象:对象拥有iter方法的
yield:带yield的函数是一个生成器,在函数内部碰到yield时,函数会返回某个值,并停留在这个位置,当下次执行函数后,会在上次停留的位置继续运行
迭代器
生成器都是迭代器
什么是迭代器:
1.有iter方法
2.有next方法
l = [2,4,6]#l是可迭代对象
a = iter(l)#a是迭代器
print(a)
l = [2,4,6]#l是可迭代对象
a = iter(l)#a是迭代器,也是生成器
print(next(a))#2
print(next(a))#4
print(next(a))#6
<list_iterator object at 0x0000026B3B8299D0>
2
4
6
作业
- 如何判断一个字符串是否是另一个字符串的子串
parson_str = "huayongkai"
son_str = input('请输入你要判断的子串:')
if parson_str.find(son_str) != -1:
print('是子串')
else:
print('不是子串')
- 如何验证一个字符串中的每一个字符均在另一个字符串中出现
def fun():
str1 = 'huayongkai'
str2 = 'qwertyuiop'
for i in str2:
if i not in str1:
return 'str2中的每一个字符不全在str1中'
return 'str2中的每一个字符全在str1中'
- 如何判定一个字符串中既有数字又有字母
def judge():
str1 = "qwert1123yuio345"
for i in str1:
if 48 <= ord(i) <= 57:
for j in str1:
if 65 <= ord(j) <= 90 or 97 <= ord(j) <= 122:
print('既有数字又有字母')
return True
else:
print('只有数字')
return False
- 做一个注册登录系统
import sys
def register():
username = input('请输入您的账户名:')
password = input('请输入您的密码:')
re_password = input('请再一次确认您的密码:')
if password == re_password:
print('恭喜您注册成功')
save_data(username, password)
else:
print('请重新注册')
def login():
username = input('请输入账户名:')
password = input('请输入密码:')
if judge_exist(username):
print('登录成功')
else:
print('账户名或密码输入有误,请重新输入!!!')
def save_data(username, password):
with open('account.txt', mode='a+') as f:
f.write(f'{username}:{password}\n')
def judge_exist(username):
with open('account.txt', mode='r') as f:
li = f.readlines()
for i in li:
name = i.split(':')
if name[0] == username:
return True
return False
def quit_login():
sys.exit(0)
option_dict = {
0: ('注册', register),
1: ('登录', login),
3: ('退出', quit_login)
}
def main():
while True:
print('欢迎来到华子ATM机'.center(150))
for i in option_dict:
print(i, option_dict[i][0])
option = eval(input('请输入您需要的功能:').strip())
if option in option_dict.keys():
option_dict[option][1]()
else:
print('请输入正确选项')
if __name__ == '__main__':
main()