python函数

函数

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))
2yield关键字
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

作业

  1. 如何判断一个字符串是否是另一个字符串的子串
parson_str = "huayongkai"
son_str = input('请输入你要判断的子串:')
if parson_str.find(son_str) != -1:
    print('是子串')
else:
    print('不是子串')
  1. 如何验证一个字符串中的每一个字符均在另一个字符串中出现
def fun():
    str1 = 'huayongkai'
    str2 = 'qwertyuiop'
    for i in str2:
        if i not in str1:
            return 'str2中的每一个字符不全在str1中'
    return 'str2中的每一个字符全在str1中'
  1. 如何判定一个字符串中既有数字又有字母
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
  1. 做一个注册登录系统
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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

^~^前行者~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值