疫情环境下的网络学习笔记 python 3.18

3.18

上节课回顾

  1. 利用f.seek()实现 tail-f

  2. 操作系统的文件是共享的,所有的应用程序都可以同时进行操作

    同时对两个文件进行操作,存在问题,暂时碰不到这种问题,将来会有解决办法

  3. 文件修改的两种方式

    • 读进内存,修改完用内存覆盖
    • 创建一个临时文件,每次修改得到新的结果,放进新的文件中,最后删除原文件,将新的文件重命名成原文件

    硬盘上没有删除一说,只有用新的覆盖旧的。删除只是把旧的内容标记为 free 状态,覆盖完了才是真的删除了

  4. 函数,为什么要用,怎么用

    def 函数名(参数名1,参数名2):
        '''文档注释'''
        代码块
        return 值
  5. 先定义后使用

    • 定义:申请内存空间将函数体代码存放起来,然后将内存地址绑定给函数名,只检测语法,不执行代码
    • 调用:通过函数名找到函数的内存,加阔号除法函数体代码的运行
  6. 定义函数三种形式:有参,无参,空

  7. 调用的三种方式:语句形式,表达式形式,参数传入

  8. return返回值:没有返回值,返回一个值,返回多个值

  9. return 是函数结束的标志,一个函数内可以有多个return,但只要执行一个,整个函数就立刻结束,并且会将该return后的值当作结果返回

正课

参数

如何用

按照定义阶段跟调用阶段分为两大类,形参,实参

形参

变量,指向一个值

在函数定义阶段定义的参数称之为形式参数,简称形参

def func(x,y)
    print(x,y)

实参

值,实际的数

调用阶段传入的值称之为实际参数,简称实参,相当于变量值

形参与实参的关系

  • 在调用阶段,实参(变量值)会赋值给形参(变量名)
  • 这种绑定关系只能在函数体内使用
  • 形参与实参的绑定在调用时生效,函数结束后解除绑定关系

实参是传入的值,但值可以是以下形式

  1.  func(1,2)
  2.  a = 1
     b = 2
     func(a,b)
  3.  func(int('1'),2)
     func(func(1,2),func(2,3),33)
    只要结果是一个值,放什么进参数都行

位置参数

按照从左到右的顺序依次定义的参数,称之为位置参数

真正与位置有关的步骤是传参

  • 位置形参

    在函数定义阶段,按照从左到右顺序直接定义的变量名。必须被传值,多一个不行,少一个也不行

    func(x,y)
  • 位置实参

    在函数调用阶段,按照从左到右的顺序依次传入的值,按照顺序与形参一一对应

    func(1,2)

关键字参数

关键字形参:在函数调用阶段,按照key = value 的形式传入的值

指名道姓给某个形参传值,可以完全不参照顺序

def fun(x,y)
    pass
    
fun(y=1,x=2)

混合使用

  • 位置实参必须放在关键字实参前,否则报错

    func(1,y=2)
  • 不能为同一个形参重复传值

    func(1,x=1,x=3)
    func(1,2,x=2,y=3)
    # 此时报错 keyword argument repeated

默认参数 形参

在定义函数的阶段,就已经被赋值的形参,称之为默认参数

  • 在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值

    def func(x, y=3):
        print(x, y)
    func(x=1)
    func(x=1,y=5)
  • 对于每次调用,都必须被传入新的值,则用位置参数或关键字参数,若大部分的使用情况下,某个参数是固定的,则可以把固定的参数设为默认参数

位置形参与默认形参混用

  1. 位置形参必须在默认形参的左边

  2. 默认参数的值在定义阶段被赋值的,准确的说被赋予的是值的内存地址

    m = 2
    def func(x,y=m):  # m的内存地址传给y,指向2
        print(x,y)
    m = 333
    func(1)
    # 输出1,2
    m = [11111,]
    def func(x,y=m):  # y指向m的内存地址,指向列表
        print(x,y)
    m.append(333)
    func(1)
    # 输出1,[11111,333]
  3. 虽然默认值可以被指定为任意数据类型,但是一般使用不可变类型:使用可变则失去了默认参数使用的意义

    函数的定义应该遵循一个原则,是能够预知它拿到的结果,只跟函数本身有关,不受外界代码影响

    def func(x,y,z,l=None):
        if l is None:
            l = []
        l.append(x)
        l.append(y)
        l.append(z)
        print(l)
    # 对于需求默认参数为可变类型,可以先默认参数为none,在函数体里面判断,如果没传入值就为可变,如果传入了值就相当于改变了默认参数
    # 所有的none都是同一个none,python中自带的类似小整数池的概念

可变长度的参数

可变长度指的是在调用函数时,传入的值(实参)的个数不固定,而实参是用来为形参赋值的,所以对应着,针对溢出的实参,必须有对应的形参来接收

可变长度的位置参数

* 形参名:用来接收溢出的位置实参,溢出的实参会被 ***** 保存成元组的格式赋值给其后的形参名

def func(x,y,*z):
    print(x,y,z)
func(1,2,3,4,5,6)
# 1 2 (3,4,5,6)

需求:对多个实参进行求和

def my_sum(*args):
    res = 0
    for item in args:
        res += item
    return res
res = my_sum(1,2,3,6,88,88)
print(res)

args

arguments的缩写

* 后面可以跟任意名字,但是约定俗成用 args 跟 * 搭配使用,一看到就知道其来自于 * 给他赋值的值

可变长度的关键字参数

** 形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给 ** 后面的任意名字

其中任意名字约定俗成是 kwargs**kwargs

def register(name,age,**kwargs):
    print(name,age,kwargs)
register(name = 'deimos',age = '12',sex ='male',cool = 'true')

星 * 用在实参中

def func(x,y,z)
    print(x,y,z)
    
func(*[11,22,33])  #实参中带星 * 先将 * 后的值打散,每一个元素作为位置参数传入
# 11,22,33

形参和实参中都带星 * / **

  • 先将实参打散成元素,再去到形参中赋值,其中溢出的部分被存成元组args
  • 被 * 打散的对象只能是可迭代对象
  • *args 必须在 **kwargs 之前:位置形参在左,关键字形参在右
  • 用于以后为函数新增参数,传参十分方便
def index(x,y,z):
    print(x,y,z)
    
def wrapper(*args,**kwargs):
    index(*args,**args)
    
wrapper(1,z=2,y=3)

将函数的参数传递给其中嵌套的函数,在定义原函数和嵌套函数的时候都使用*args和**kwargs,可以将参数的格式转换为嵌套函数的格式

猜你喜欢

转载自www.cnblogs.com/telecasterfanclub/p/12517828.html