python进阶学习 day_01

学习内容:

1.1 函数的定义

        在python中函数是指可以重复执行的语句块,可以重复调用,作用是为了封装语句块, 提高代码的重用性,函数是面向过程编程的最小单位

1.1.1 def语句

        def 语句的作用是用来定义(创建)函数的
        注意:1. 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
                   2. 函数名是一个变量,不要轻易对其赋值
                   3. 函数有自己的名字空间,在函数外部不可以访问函数内部的变量,在函数内部可以                         访问函数外部的变量,但不能轻易对其改变
                   4. 函数的形参列表如果不需要传入参数,形式参数列表可以为空
                   5. 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
                   6. 函数内容以冒号 : 起始,并且缩进
                   7. return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相                           当于返回 None
        语法:def 函数名(形式参数列表):
                           语句块
        示例:
 

# 定义一个函数,用 say_hello 变量绑定
def say_hello():
    print("hello world!")
    print("hello tarena!")
    print("hello everyone!")
    
# 定义一个函数,传入两个参数,让这个函数把最大的值打印到终端
def mymax(a, b):
    if a > b:
        print("最大值是", a)
    else:
        print("最大值是", b)

1.1.2 函数的调用

        函数调用是一个表达式,如果函数内没有return 语句,函数执行完毕后返回 None 对象
语法:函数名(实际调用传递参数)
        示例:
 

# 调用
say_hello()  # 调用一次
say_hello()  # 调用第二次

# 调用
mymax(100, 200)
mymax(999, 1)
mymax('abc', 'cba')

1.1.3 return 语句

        return 用于函数的内部,结束当前函数的执行,返回到调用此函数的地方,同时返回一个对    象的引用关系,具体说明:
        1. return 语句后面的表达式可以省略,省略后相当于 return None
        2. 如果函数内部没有 return 语句, 则函数执行完毕后返回None, 相当于在最后一条语句后有一条return None
        示例:

def say_hello():
    print("hello aaa")
    print("hello bbb")
    return 1 + 2
    print("hello ccc") # 不会执行


r = say_hello()
print(r)  # 3

1.2 函数参数

1.2.1 形参和实参

形参:形参是函数定义时声明的参数,用于接收调用函数时传递的值。形参是函数内部的局部变量,只在函数体内有效
实参:实参是调用函数时传递给函数的具体值或变量。实参会传递给形参,从而在函数内部使用
        示例:

def add(a, b):  # a 和 b 是形参
    return a + b

result = add(3, 5)  # 3 和 5 是实参

1.2.2 可变参数与不可变参数

        在 python 中,strings,tuples,numbers,bool和None 是不可更改的对象,而 list,dict及set      等则是可以修改的对象
        不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10                可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了再让 a 指向它,而 5 被丢弃,不是改变a 的值,相当于新生成了 a.
python 函数的参数传递:
        不可变类型:值传递:  如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象
        可变类型:引用传递:  如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
        示例:
        1. 传不可变对象实例(通过内置的 id() 函数来查看内存地址变化). 

def change(a):
    print(id(a))

a = 10
change(a)  # 1428793408
a = 1
change(a)  # 1428793264
# 总结:可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的id。

        2. 传可变对象实例(可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了).

def changeme(mylist):
    mylist.append(40)
    print(mylist)

mylist = [10, 20, 30]
changeme(mylist)  # [10, 20, 30, 40]
print(mylist)  # [10, 20, 30, 40]
# 总结:传入函数的和在末尾添加新内容的对象用的是同一个引用

1.2.3 函数的形式参数定义方法

        python中形参的定义有五种:位置形参、默认参数、星号元组形参(*args)、命名关键字形参、双星号字典形参(**kwargs)

        1)位置形参:位置形参是最常见的参数类型,它们按照定义的顺序传递给函数.
        语法:def 函数名(形参名1, 形参名2, ...):
                            pass
        示例:

def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # 输出: 8

        2)缺省参数(默认参数):在 Python 中,默认参数在函数定义时只计算一次。建议默认参  数使用不可变对象,或将默认参数设置为 `None`,并在函数内部进行初始化。如果默认参数是一个可变对象(如列表或字典),可能会导致意外行为.
        语法:def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ... ):
                     pass
        注意:缺省参数即默认实参,必须自右向左依次存在(即,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数).
        示例:

def myadd4(a, b, c=0, d=0):
    print(a)
    print(b)
    print(c)
    print(d)
    return a + b + c + d

print(myadd4(1, 2))
print(myadd4(1, 2, 3))
print(myadd4(1, 2, 3, 4))

'''
def myadd(a, b=0, c):  # 报错
    pass

'''

        3)星号元组形参:星号元组形参允许函数接受任意数量的位置参数,并将这些参数打包成一个元组,元组形参名一般命名为args.
        语法:def 函数名(*元组形参名):
                    pass
        示例:

def myfunc2(*args):
    print("len(args)=", len(args))
    print('args=', args)

myfunc2()  # args=()
myfunc2(1, 2, 3)  # args=(1, 2, 3)

def myfunc3(a, b, *args):
    print(a, b, args)

myfunc3(1, 2)  # 1-->a, 2-->b, ()--->args
myfunc3(1, 2, 3, 4)  # # 1-->a, 2-->b, (3, 4)--->args

        4)命名关键字形参:命名关键字形参是指在函数定义中,必须通过关键字传递的参数,它们通常出现在 ' * ' 或 ' *args ' 之后,' *args ' 用于在函数定义中接收任意数量的位置参数,并将它们打包成一个元组(tuple);' * ' 是一个分隔符,用于在函数定义中分隔普通位置参数和命名关键字参数。它本身不接收任何参数,而是强制其后的参数必须通过关键字传递.
        注意:命名关键字参数强制所有的参数都必须用关键字传参,如果命名关键字参数在定义时指定了默认值(即缺省参数),则调用时可以不传递实参,函数会使用默认值,如果在定义时没有指定默认值,则调用时必须传递实参,否则会抛出 ' TypeError ' .
        语法:def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):
                           pass
                   def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ...):
                           pass
        示例:

# 函数只接受命名关键字参数,调用这个函数时,所有的参数都必须通过关键字来传递
def my_function(*, a, b):
    print(a, b)

# 正确的调用方式
my_function(a=1, b=2)
my_function(3, a=1, b=2)  # 错误

# my_function 定义时使用了 * 分隔符,表示它不接受任何位置参数。3 是一个位置参数,但函数定义中并没有位置形参来接收它。
def my_function(*args, a, b):
    print(a, b)

my_function(a=1, b=2)
my_function(3, a=1, b=2)

# *args 用于在函数定义中接收任意数量的位置参数,并将它们打包成一个元组(tuple)。
def myfunc4(a, b, *args, c, d):
    print(args)
    print(a, b, c, d)

myfunc4(1, 2, d=4, c=3)  # 正确,c,d 必须关键字传参
myfunc4(1, 2, 5, 6, d=4, c=3)  # 正确,c,d 必须关键字传参,5,6作为元组输入
myfunc4(1, 2, 3, 4)  # 错误

        5)双星号字典形参:双星号字典形参允许函数接受任意数量的关键字参数,并将这些参数打包成一个字典.
        注意:字典形参名最多有一个,字典形参名 一般命名为 kwargs .
        语法:def 函数名(**kwargs):
                           pass
        示例:

def myfunc5(**kwargs):
    print(kwargs)

# {'name': 'tarena', 'age': 18}-->kwargs
myfunc5(name='tarena', age=18)


def func03(**kwargs):
    for k, v in kwargs.items():
        print(k, v)

func03(a=1, b=2)

1.2.4 函数的调用传参

        位置传参:实际参数传递时,实参和形参按位置来依次对应.
        关键字传参:实际参数传递时,实参和形参 按名称依次对应.
        注意: 位置传参要先于关键字传参.
        参数解包:如果调用时已经有一个元组或列表,可以使用 ' * ' 解包传递给函数;如果有一个字典,可以使用 ' ** ' 解包传递关键字参数.
        示例:

def myfun1(a, b, c):
    print('a=', a)
    print('b=', b)
    print('c=', c)

## 位置传参
myfun1(1, 2, 3)
## 关键字传参
myfun1(c=33, a=11, b=22)
## 位置传参要先于关键字传参
myfun1(111, c=333, b=222)  # 正确

# 序列实参:使用星号将序列拆分后,与形参进行对应
# 序列实参的长度必须与形参的数量一致。
list01 = [7, 8, 9]
myfun01(*list01)

# 字典实参:使用双星号将字典拆分后,依次与形参对应
# 字典实参的键必须与形参的名称一致。
dict01 = {"c": 3, "b": 2, "a": 1}
myfun01(**dict01)

# 序列实参和字典实参混合使用
list = [1]
dic = {'b': 2, 'c': 3}
myfun1(*list, **dic)

1.3 返回值

        python中函数可以使用 ' return ' 语句来返回一个或多个值,如果没有明确的 ' return ' 语句,函数将默认返回 ' None ' .
        示例:

# 没有return
def fn1():
    print("调用了函数")

re = fn1()
print(re)  # None

# 返回一个值
def fn2(x):
    return x + 100

re2 = fn2(100)
print(re2)  # 200

# 返回多个值
def fn3(x):
    return x * x, x % 3

re3 = fn3(100)
print(re3)  # (10000, 1)
x, y = fn3(100)
print(x, y)  # 10000 1

1.4 匿名函数

        在Python中,匿名函数通常使用 ' lambda ' 关键字来创建。匿名函数也被称为 lambda 函数,它是一种简单的、一行的函数,常用于临时需要一个小函数的地方.
        语法:lambda[函数的参数列表]: 表达式
        作用:lambda 表示创建一个匿名函数对象,其中 lambda 是关键字,表示你正在定义一个匿名函数,同 def 类似,但不提供函数名(' [函数的参数列表] '是函数的参数,可以有零个或多个参数,参数之间用逗号分隔;' : 表达式 ' 是函数的返回值,通常是一个表达式,匿名函数会计算这个表达式并返回结果)
        注意:lambda 表达式的创建函数只能包含一个表达式.
        示例:

def myadd(x, y):
    return x + y

print('1 + 2 =', myadd(1, 2))  # 3

# myadd 函数可以改写成 
myadd2 = lambda x, y: x + y
print('3 + 4 =', myadd2(3, 4))  # 7

square = lambda x: x * x
print(square(5))  # 输出: 25

1.5 变量作用域

        变量作用域:指 一个变量声明以后,在哪里能够被访问使用,就是这个变量"起作用"的区域:也就是这个变量的作用域,一般来说,变量的作用域,是在函数内部和外部的区域 来体现,因此常常与函数有关.
        变量分为局部变量全局变量.
        局部变量:定义在函数内部的变量称为局部变量(函数的形参也是局部变量),函数内部的变量只能在函数内部或者函数内部的函数内部访问 ,函数外部不能访问,并且局部变量在函数调用时才能够被创建,在函数调用之后会自动销毁.
        全局变量:定义在函数外部,模块内部的变量称为全局变量,定义的全局变量能让所有函数都可以直接访问(取值,但函数内部不能直接将其赋值改变).
        局部变量示例:

def fn(a, b):
    c = 100
    print(a, b, c)    # a, b, c三个都是局部变量
fn(1, 2)
# print(a, b, c)   # 报错, 因为a,b,c 在调用后就销毁了

        全局变量示例:

a = 100  # 全局变量

def fx(b, c):  # b, c 局部变量
    d = 400  # d 局部变量
    print(a, b, c, d)

fx(200, 300)
print(a)  # 100
# print(b)  # 报错, 因为此时 b 不存在了

b = 100  # 全局变量

def fx(c):
    b = 666  # 创建局部变量,不是改变全局变量
    d = 300
    print(b, c, d)  # 优先访问局部变量

fx(200)  # 666 200 300
print(b)  # 100

        嵌套函数:嵌套函数是指在一个函数内部定义的另一个函数。它可以像普通函数一样使用,但通常是作为外部函数逻辑的一部分,内部函数可以将一些复杂的逻辑隐藏在外部函数内部,只暴露必要的接口,隐藏实现细节,具有更强的局部化和封装性,并且嵌套函数的外部函数可以调用内部函数,函数也可以看作是定义在作用域中的数据,在执行函数的时候,要遵循优先在自己的作用域中寻找,没有则返回到上一层的作用域寻找.
        示例1:定义两个全局函数func,execute,其中 execute 调用 func .

def func():
    print('func')

def execute():
    print('execute')
    func()

execute()

        现在定义两个 func 函数,一个在 execute 外部,一个在 execute 内部.

def func():
    print('func')

def execute():
    print('execute')

    def func():
        print('local func')

    func()

execute()

        示例2:当同一作用域里面出现了两个同名函数时,后面的会将前面的同名函数覆盖.

def func():
    print('func')

def execute():
    print('execute')

    def func():
        print('local func')

    func()

def func():
    print('new func')

execute()
func() # 输出:execute    local func     new func

        示例3:当内部函数执行时需要变量,如果在局部作用域中找不到,则到上层作用域中找.

def execute():
    name = 'zhangsan'

    def inner():
        print(name)

    inner()

execute() # 输出 zhangsan

        示例4:嵌套函数可以访问外部函数的变量和参数,但外部函数不能直接访问内部函数的变量.        

def outer():
    x = 10  # 外部函数的变量

    def inner():
        y = 20  # 内部函数的变量
        print(f"x: {x}, y: {y}")  # 内部函数可以访问外部函数的变量

    inner()
    print(y)  # 错误:外部函数不能访问内部函数的变量

outer()

        示例5:函数的返回值可以是一个函数.

def execute():
    name = 'zhangsan'

    def inner():
        print(name)

    return inner


inner = execute()
print(type(inner))
inner() # <class 'function'>   zhangsan

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值