06,函数和函数的进阶

1,函数的初识

函数:以功能(完成一件事)为导向。例如:登录,注册。一个函数就是一个功能
随调随用
优点:1,减少代码的重复性。2,增强代码可读性
# 函数式编程
s1 = 'cfgjsxdfgdzfjkghiasvhidfgb'
l1 = [1, 5, 5, 3, 8, 5, 5, 8, 9, 4, 4, 4]


def my_len(s):
    count = 0
    for i in s:
        count += 1
    return count


print(my_len(s1))
print(my_len(l1))
结构:
    def 关键字,定义函数。
    meet 函数名:与变量设置相同,具有可描述性。
    函数体:有缩进。
def meet():
    print('打开tantan')
    print('左滑一下')
    print('右滑一下')
    print('找人')
    print('悄悄话')
    print('约....走起')
    return '妹子一枚', 132, [22, 33, 44]


ret = meet()  # 将print里面的内容返回给ret
print(ret, type(ret))    # ('妹子一枚', 132, [22, 33, 44]) <class 'tuple'>

return:总结
    1,在函数中,终止函数
    2,return 可以给函数的执行者返回值
        1,return单个值     单个值
        2,return多个值     (多个值,)元组形式

2,函数的参数

形参

1,位置参数

def meet(sex, age, skill):
    print('进行筛选:性别:{},年龄{},{}'.format(sex, age, skill))


meet('男', '25', 'python技术好的')

2,关键字参数

def meet(sex, age, skill, hight, weight):
    print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))


meet('男', '25', 'python技术好的', 180, 60)
meet(sex='男', age='25', skill='python技术好的', hight=180, weight=60)       # 关键字传参,必须一一对应,可以不按顺序

3,混合参数

def meet(sex, age, skill, hight, weight):
    print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))
    return '进行筛选:性别:{},年龄{}'.format(sex, age)


meet('男', '25', skill='python技术好的', hight=180, weight=60)  # 既有位置参数,也有关键字参数 位置参数一定在关键字参数前面
# 进行筛选:性别:男,年龄25,python技术好的,身高是180,体重60  混合参数

4,默认值参数

def meet(age, skill, hight, weight, sex='女'):  # sex='女',就是默认参数,写到最后面
    print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))
    return '进行筛选:性别:{},年龄{}'.format(sex, age)


meet('25', 'python技术好的', hight=180, weight=60, sex='男')  # 还可以强制修改

实参

函数执行时使用的参数

def meet(sex):  # 函数的定义:sex接受的参数形式参数
    print('进行筛选:性别:{}'.format(sex))



meet('女')  # '女'函数执行的参数:实际参数

3,函数的参数(2)

形参的角度

def eat(a, b, c, d):
    print('我请你吃:{}\t{}\t{}\t{}'.format(a, b, c, d))

eat('鸡', '鸭', '鱼', '肉')
此时增加内容就需要修改源码
def eat(a, b, c, d, e, f):
    print('我请你吃:{}\t{}\t{}\t{}'.format(a, b, c, d, e, f))

eat('鸡', '鸭', '鱼', '肉', '蛋', '蔬')

1,万能参数。*args

万能参数:*args,约定成俗的
*函数定义时:*代表聚合。将所有的位置参数聚合成一个元组,赋值给了args。
def eat(*args):
    print('我请你吃:{}\t{}\t{}\t{}'.format(*args))


eat('鸡', '鸭', '鱼', '肉', '蛋', '蔬')
# 练习
# 写一个函数,计算你传入函数的所有的 数字的和
def add(*args):
    sum1 = 0
    for i in args:
        sum1 += i
    return sum1


s = add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(s)

2,万能参数  **kwargs

在函数的定义值时:**将所有的关键字参数聚合到一个字典,将这个字典赋值给了kwargs。
def func(**kwargs):
    print(kwargs)


func(name='alex', age=19, sex='男')
万能参数:*args,**kwargs,
def func(*args, **kwargs):
    print(args)
    print(kwargs)


func('1,2,3,4', name='564')

 3,参数的位置顺序

def func(a, b, *args, sex='男', c, **kwargs):
    print(a, b)
    print(sex)
    print(args)
    print(c)
    print(kwargs)


func(1, 2, 3, 4, 5, 6, 7, sex='女', name='alex', age=18, c=666)  # c 必须要关键字传参
形参角度的最终顺序:位置参数,*args,默认参数,仅限关键字参数,**kwargs 

4,名称空间

 三种名称空间

名称空间也是命名空间
prthon分为三个空间:
    1,全局名称空间(当前py文件)
    2,局部名称空间(函数,并且是存在于函数执行时)
    3,内置名称空间(builtins.py)
全局名称空间:
    就是记录的是整个文件中的变量与值的对应关系,以及函数名与函数体的对应关系的内存空间
    随着代码的结束而消失
a = 1
b = 2


def func():
    print(666)


c = 3
局部名称空间(临时名称空间):
    就是记录函数体里的变量与值的对应关系
    随着函数的结束而消失
a = 1
b = 2
def func():
    f = 5        # 只能在函数体中使用
    print(f)
c = 3
func()
内置名称空间:
    python源码给你提供的一些内置函数,如:print(),input()...

空间的加载顺序

内置名称空间 ----> 全局名称空间 ----> 局部名称空间(函数执行时)
取值顺序(就近原则) (单向不可逆只能是,局 --> 全 --> 内)
# 取值顺序(就近原则) (单向不可逆只能是,局 --> 全 --> 内)
name = 'alex'            # 全局变量


def func():
    name = '太白'        # 局部变量
    print(name)


func()


print(input)  # <built-in function input>        # 内置变量

作用域

两个作用域:
    1,全局作用域:
        内置名称空间 全局名称空间
    2,局部作用域:
        局部名称空间
局部作用域可以调用全局作用域
date = '周五'


def func():
    # print(date)
    return date


print(func())      # 周五

def func():
    a = 10
    print(a)

func()
print(a)        # NameError: name 'a' is not defined,全局不能调用局部
# 只引用,不修改,例--两个count不是同一个count,因为存储地址不同
count = 1


def func():
    count = 100
    print(id(count))


func()      # 140707257224560
print(id(count))        # 140707257221392
局部作用域不能改变全局作用域,当python解释器读取到局部作用域时,发现你对一个变量进行修改操作。
解释器会认为你在局部已经定义过这个局部变量了,他就从局部找这个局部变量,找不到报错
count = 100

def func():
    # count += 1
    print(id(count))


func()
print(id(count))


def func():
    count = 1

    def inner():
        print(count)

    inner()


func()

5,内置函数(题目,检测函数执行过程的掌握)

输出的顺序

# 例1
def func1():
    print('in func1')
    print(3)


def func2():
    print('in func2')
    print(4)


func1()
print(1)
func2()
print(2)



# 例2
def func1():
    print('in func1')
    print(3)


def func2():
    print('in func2')
    func1()
    print(4)


print('===============')
print(1)
func2()
print(2)


# 例3
def fun2():
    print(2)

    def fun3():
        print(6)

    print(4)
    fun3()
    print(8)


print('===============')
print(3)
fun2()
print(5)


答案:例1:in func1,3,1,in func2,4,2

        例2:1,in func2,in func1,3,4,2

        例3:3,2,4,6,8,5

6,global,nonlocal

默认参数的陷阱

陷阱只针对与默认参数是可变的数据类型

# 例1
def func(name, sex='男'):
    print(name)
    print(sex)


func('alex')

# 例2
def func(name, alist=[]):
    alist.append(name)
    return alist


ret = func('alex')
print(ret, id(ret))     # ['alex'] 2996731269640
ret2 = func('太白金星')
print(ret2, id(ret2))       # ['alex', '太白金星'] 2996731269640

例子:

1,

def func(a, list=[]):
    list.append(a)
    return list


print(func(10))       # [10]
print(func(20, []))     # [20]
print(func(100))      # [10, 100]
上面的程序相当于:
执行一步打印一次
l1 = []
l1.append(10)
print(l1)
l2 = []
l2.append(20)
print(l2)
l1.append(100)
print(l1)

2,

def func(a, list=[]):
    list.append(a)
    return list


ret1 = func(10, )
ret2 = func(20, [])
ret3 = func(100, )

print(ret1)         # [10, 100]
print(ret2)         # [20]
print(ret3)         # [10, 100]
全部执行完再打印

局部作用域的坑

在函数中,如果定义一个变量,但是在定义这个变量之前引用了这个变量,那么解释器认为:语法错误

count = 1
def func():
     count += 1
     print(count)

func()

# 在函数中,如果定义一个变量,但是在定义这个变量之前引用了这个变量,那么解释器认为:语法错误
count = 1
def func():
     print(count)
     count = 3
func()

global  nonlocal

global
1,在局部作用域中声明一个全局变量。

必须先调用函数,再输出被声明的局部变量

# 例子
name = 'alex'

def func():
    name = '太白金星'
    name1 = 'alex'
    print(name, name1)


func()  # 太白金星 alex
print(name1)  # 报错




# 对比例子

def func():
    global name1
    name = '太白金星'
    name1 = 'alex'
    print(name, name1)


func()              # 太白金星 alex
print(name1)        # alex
# 必须先调用函数,再输出被声明的局部变量
2,修改全局变量
count = 1


def func():
    global count
    count += 2
    print(count)


print(count)        # 1
func()        # 3
print(count)        # 3
nonclocal
1,不能操作全局变量
# 例1
count = 1
def func():
     nonlocal count
     print(count)

func()
# 反例
count = 1
def func():
     print(count)

func()

2,可以内层函数对外层函数的局部变量进行修改。
def wrapper():
     count = 1
     def inner():
          nonlocal count
          count += 1
     print(count)
     inner()
     print(count)
wrapper()

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值