随笔 - 755  文章 - 0 评论 - 33 阅读 - 135万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

一、函数的基本使⽤

函数的作⽤,在开发程序时,使⽤函数可以提⾼编写的效率以及代码的重⽤

函数的定义:  程序是一个被命名的、独立的,完成特定功能的一段代码,并可能给调用它的程序一个返回值。

def 函数名([参数1, 参数2, ...]): 
函数封装的代码 
    ……
  [return 返回值]

1.def 是英⽂ define 的缩写

2.函数名称 应该能够简单明确的表达 函数功能,以⽅便后续的调⽤

3.函数名称 的命名应该 符合 标识符的命名规则

  可以由 字⺟、下划线 和 数字 组成

  不能以数字开头

  不能与关键字重名

函数调用

调⽤函数很简单的,通过 函数名() 即可完成对函数的调⽤

注意:不能将 函数调⽤ 放在 函数定义 的上⽅,因为在 使⽤函数名 调⽤函数之前,必须要保证 Python 已经知道函数的存在

函数的⽂档注释

在开发中,如果希望给函数添加注释,应该在 定义函数 的下⽅,使⽤连续的三对引号

在 连续的三对引号 之间编写对函数的说明⽂字

在 函数调⽤ 位置,使⽤快捷键 CTRL + Q 可以查看函数的说明信息

def func_sum(): 
    """求和 1+2""" 
    sum_num = 1 + 2 
    print(sum_num) 
func_sum()

二、函数的参数

函数的参数,可以传递数据给函数内部,增加函数的 通⽤性

设置函数的参数

在函数名的后⾯的⼩括号内部填写 参数

多个参数之间使⽤ , 分隔

def sum_2_num(num1, num2): 
    result = num1 + num2 
    print("%d + %d = %d" % (num1, num2, result)) 
sum_2_num(50, 20)

形参和实参

形参:定义函数 时设置的参数,是⽤来 代替真实数据 的,在函数内部作为变量使⽤

实参:调⽤函数 时设置的 真实数据,会被传递到 函数内部

a = 5
def test1(a):
    a += 1
    print("%d" % a)
test1(2)
print("%d" % a)

结果为3、5

形参的作⽤域(起作⽤的范围) 只在定义函数的代码块 中,⼀旦超出该范围再使⽤该形参名,则使⽤的是 同名的⾃定义变量

编程中应该尽量避免 函数的形参 和 同⽂件的变量名 同名

三、函数的返回值

设置返回值

在函数中使⽤ return 关键字可以返回结果

def sum_2_num(num1, num2):
    """对两个数字的求和"""

    return num1 + num2
    # 调⽤函数,并使⽤ result 变量接收计算结果
result = sum_2_num(10, 20)
print("计算结果是 %d" % result)

注意: return 表示返回,后续的代码都不会被执⾏

4种函数的类型

函数根据有没有参数,有没有返回值,可以相互组合,⼀共有4种

  ⽆参数,⽆返回值

  ⽆参数,有返回值

  有参数,⽆返回值

  有参数,有返回值

四、局部变量(函数内部)

变量的作用域:变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用),主要分为两类:全局作用域与局部作用域。在函数内部定义范围就称之为局部作用域,在函数外部(全局)定义范围就是全局作用域.

在Python中,定义在函数外部的变量就称之为全局变量;定义在函数内部变量就称之为局部变量。

局部变量,就是在 函数内部定义的变量

不同的函数,可以定义相同的名字的局部变量,但是各⽤个的不会产⽣影响

局部变量的作⽤域只在函数内部

局部变量的⽬的是 存储需要临时保存的数据

复制代码
# 函数中的两个局部变量虽然同名,但互不影响 
def test1(): 
    a = 10 
   print("%d" % a) def test2(): a = 5
   print("%d" % a) test1() test2()
复制代码

五、全局变量(函数外部)

在函数外边定义的变量叫做 全局变量

全局变量能够在所有的函数中进⾏访问

复制代码
# 定义全局变量 
a = 100 
def test1(): 
    print(a) 
def test2(): 
    print(a) 
# 调⽤函数 
test1()
test2()
复制代码

结果:

100
100

函数内修改全局变量

a = 10
def test():
    a = 5
    print("函数内a:%d" %a)
test()
print("函数外a:%d" %a)

结果

函数内a:5
函数外a:10

函数内赋值变量 时,默认为定义并赋值局部变量,赋值后获取的也是局部变量的值

如果在函数中修改全局变量,那么就需要使⽤ global 进⾏声明,否则出错

a = 10
def test():
    global a
    a = 5 # 修改全局变量
    print("函数内a:%d" %a)
test() 
print("函数外a:%d" %a)

结果如下:

函数内a:5
函数外a:5

 

六、多个返回值

当返回多个数据时,python会⾃动将数据 组包 成元组

如果使⽤多个变量接收返回值,python会⾃动将元组 拆包 成单个数据

复制代码
def func2():
    return 1, 1.5
a = func2()
print(a)
a, b = func2()
print(a)
print(b)
a, b, c = 1, 1.5, "hello"
print(a)
print(b)
print(c)
复制代码

结果

(1, 1.5)
1
1.5
1
1.5
hello

 

七、默认参数

形参设定默认值 称为 默认参数

调⽤函数时,如果没有传⼊默认参数对应的实参,则实参使⽤默认值。

def printinfo(name, age = 35):
    # 打印任何传⼊的字符串
    print("Name: %s" % name)
    print("Age: %s" % age)
# 调⽤printinfo函数
printinfo("miki")
printinfo("miki", 20)

结果

Name: miki
Age: 35
Name: miki
Age: 20

注意:默认参数⼀定要位于参数列表的最后⾯

# 1.默认参数(缺省参数)
    def user_info(name, age, gender=''):
        print(f'我的名字{name},今年{age}岁了,我的性别为{gender}')
    user_info('李林', 25)
    user_info('振华', 28)
    user_info('婉儿', 18, '')

结果:

我的名字李林,今年25岁了,我的性别为男
我的名字振华,今年28岁了,我的性别为男
我的名字婉儿,今年18岁了,我的性别为女

 

八、关键字参数

函数参数的两种传递方式:

一、位置传参

    def user_info(name, age, address):
        print(f'我的名字{name},今年{age}岁了,家里住在{address}')
    # 调用函数(使用位置参数)
    user_info('Tom', 23, '美国纽约')

二、关键词传参

    def user_info(name, age, address):
        print(f'我的名字{name},今年{age}岁了,家里住在{address}')
    # 调用函数(使用关键词参数)
    user_info(name='Tom', age=23,address='美国纽约')

调⽤函数时,实参可以指定对应的形参,称为 关键字参数

def printinfo(name, age):
    # 打印任何传⼊的字符串
    print("Name: %s"% name)
    print("Age: %s" % age)
printinfo(age=9,name="miki" )

结果

Name: miki
Age: 9

 

九、不定长参数/可变参数

不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
1、包裹位置参数

args

函数可以定义 可变参数,⽤于接收任意数量的参数

可变参数的前边需要添加*,⽤于提示python解释器该参数为可变参数

使⽤可变参数直接⽤args即可(不需要加*)

可变参数的本质是 将传递的参数包装成了元组

复制代码
def sum_num(a, b, *args):
    result = a + b
    for temp in args:
        result += temp
    return result
val = sum_num(1, 2, 3, 4, 5)
print("值为%d" % val)
# 关键字参数⼀旦使⽤,所有实参都要使⽤,除⾮该实参对应的是可变参数 #
# sum_num(1, 2, 3, 4, a=5)
val1 = sum_num(a=5, b=4)
print("值为%d" % val1)
复制代码

结果

值为15
值为9

例2:

  def user_info(*args):
        # print(args) # 元组类型数据,对传递参数有顺序要求
        print(f'我的名字{args[0]},今年{args[1]}岁了,住在{args[2]}')
    # 调用函数,传递参数
    user_info('Tom', 23, '武汉')
结果:
我的名字Tom,今年23岁了,住在武汉

 2、包裹关键词参数

kwargs

可变参数还有⼀种形式 可以接收不存在的关键字参数

定义参数时需要在变量名前添加两个*

这种可变参数会将 不存在的关键字参数包装成字典

def sum_num(a, b, *args, **kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)
sum_num(1, 2, 3, 4, 5, mm=5, nn=6)

结果

1
2
(3, 4, 5)
{'mm': 5, 'nn': 6}

例1:

    def user_info(**kwargs):
        # print(kwargs) # 字典类型数据,对传递参数没有顺序要求,格式要求key = value值
        print(f'我的名字{kwargs["name"]},今年{kwargs["age"]}岁了,住在{kwargs["address"]}')
    # 调用函数,传递参数
    user_info(name='Tom', address='武汉', age=23)

结果:我的名字Tom,今年23岁了,住在武汉

传递可变参数

复制代码
def sum_num(a, b, *args, **kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)
    test(*args, **kwargs)
def test(*args, **kwargs):
    print(args)
    print(kwargs)
sum_num(1, 2, 3, 4, 5, mm=5, nn=6)
复制代码

结果

1
2
(3, 4, 5)
{'mm': 5, 'nn': 6}
(3, 4, 5)
{'mm': 5, 'nn': 6}

 

十、拆包

拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常

除了对元组拆包之外,还可以对列表、字典等拆包

对字典进行拆包,取出来的是key,⽽不是键值对

复制代码
def get_my_info():
    high = 178
    weight = 100
    age = 18
    return high, weight, age
# result = get_my_info()
# print(result)
my_high, my_weight, my_age = get_my_info()
print(my_high)
print(my_weight)
print(my_age)
复制代码

结果

178
100
18

 

十一、引⽤

1、普通变量的引用,变量赋值时,赋的是值的内存地址,变量指向的是值所在内存中的地址。

看上去是值传递,实际上是引用地址的传递。传递的是地址,这样就不用去找值,速度会更快,而用的是地址中的值。

2、列表的引用:是引用地址在传递,而不是值在传递。

a = [1,2]
b = a
a.append(3)
print(a)
print(b)
print(id(a))
print(id(b))

结果:

[1, 2, 3]
[1, 2, 3]
2223509095040
2223509095040

 

3、小数字缓存池:当我们执行Python程序的时候,Python解释器会将 -5~256之间的数全部开辟好空间

a = 10
b = 10
print(id(a))
print(id(b))

结果:两个地址一样

2963836594768
2963836594768

 

 但是Python解释器为了提升性能,如果之前定义了的值都会缓存起来

a = 257
b = 257
print(id(a))
print(id(b))

结果:相同

1750546741584
1750546741584

  -5~256之间的数,不管你是怎么计算得来的,都是同一个地址,如果超出了这个范围,则不是同一个地址

a = 256
b = int(25.6*10)
print(id(a))
print(id(b))

结果:

2493375801744
2493375801744

如果超出了这个范围,则不是同一个地址

a = 257
b = int(25.7*10)
print(id(a))
print(id(b))

结果:

2034141329744
2034141329808

4、字符串缓存:最大缓存位数是20位。

str1 = "hello"
str2 = "hello"
print(id(str1))
print(id(str2))

结果:

2465391472816
2465391472816

 

总结:

1)、两个变量引用的内存地址相同,那么这两个变量的值肯定相同

2)、两个变量引用的内存地址不同,变量的值有可能相同

python中可以使⽤ id函数查看引⽤的是否为同⼀个内存空间,如果返回值相同,说明引⽤相同

在python中,值是靠引⽤来传递的。

复制代码
>>> a = 1 
>>> b = a 
>>> id(a) 
13033816 
>>> id(b) # 注意两个变量的id值相同 
13033816 
>>> a = 2 
>>> id(a) # 注意a的id值已经变了 
13033792 
>>> id(b) # b的id值依旧 13033816
复制代码
复制代码
>>> a = [1, 2] 
>>> b = a 
>>> id(a) 
139935018544808 
>>> id(b) 
139935018544808 
>>> a.append(3) 
>>> a [1, 2, 3] 
>>> id(a) 
139935018544808 
>>> id(b) # 注意a与b始终指向同⼀个地址 
139935018544808
复制代码

十二、可变类型与不可变类型

可变类型:就是可以修改存储空间中的数据,内存地址不变

不可变类型就是存储空间中的数据不能修改。

a = 1
print(id(a))
a = 2
print(id(a))

结果:

2169985722672
2169985722704

说明数值类型是不可变类型

可变类型,值可以改变:

  列表 list(增删改时,值变了,但是地址没变)

  字典 dict

dict1 = {"a" : 10}
print(id(dict1))
dict1["age"] = 18
print(id(dict1))

结果:

1691438038336
1691438038336

 

不可变类型,值不可以改变:

  数值类型 int, long, bool, float

  字符串 str

  元组 tuple

 函数的默认参数尽量不要使用可变类型。

tuple = (1,2)
tuple[1] = 3
print(tuple)

结果:

 但是如果对tuple中的list进行修改,则没问题。

list1 = [1,2]
tuple = (list1,3)
tuple[0].append(3)
print(tuple)

结果:

([1, 2, 3], 3)

十三、lambda表达式(匿名函数)

如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda简化。
基本语法:
lambda 参数列表 : 表达式

普通函数

    def fn1():
        return 100
    print(fn1)
    print(fn1())

结果:

<function main.<locals>.fn1 at 0x000002A508157740>
100

lambda表达式

fn2 = lambda: 100
print(fn2)
print(fn2())

结果:

<function main.<locals>.<lambda> at 0x000001F74D627740>
100
注意:直接打印lambda表达式,输出的是此lambda的内存地址

带参数的lambda表达式

(1)、带普通参数的lambda表达式

fn1 = lambda a, b: a +b
print(fn1(1, 2))

结果: 3

(2)、带默认值参数的lambda表达式

fn1 = lambda a, b,c=100: a + b + c
print(fn1(10, 20))

结果: 130

(3)、带包裹位置参数的lambda表达式

fn1 = lambda *args: args
print(fn1(10, 20, 30))

结果:(10, 20, 30)

(4)、带包裹关键词的lambda表达式

fn1 = lambda **kwargs: kwargs
print(fn1(name='python',age=20))

结果:

{'name': 'python', 'age': 20}

 

 

 

 

 

 



感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接
posted on   周文豪  阅读(215)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示