今天是学习python的第五条 今天的知识点倒不是特别多 但是会有一个用函数写的学生管理系统

以下是今天的知识点:

python socket拆包组包_数据


python socket拆包组包_全局变量_02


python socket拆包组包_全局变量_03


0. 列表 推导式

格式: 列表变量 = [表达式 for 变量 in range(10)]
表达式中需要使用后面的变量

使用列表推导式来完成列表的创建
c_l = [i for i in range(100)]
c_l = [x for i in range(100)] # 注意,表达的变量(x)使用要和循环中的变量(i)一致

print(c_l)
print(len(c_l))

列表推导 式,带条件的
实现列表 中所有的值 都 是3的倍数
c_l = [x for x in range(1,101) if x % 3 == 0]
print(c_l)

创建一个列表 ,列表 中的每个元素都 是具有两个值 的元组

c_l = [(x,x) for x in range(10)]
 c_l = [(x,) for x in range(10)]
 c_l = [(x,y) for x in range(10) for y in range(3)]
print(c_l)

1.组包和拆包

组包: 将多个值同时赋给一个变量时,解释器会进行自动组包操作
拆包: 将一个容器值(元组),里面的多个数据同时赋值多个变量,解释器会进行拆包操作
注意: 拆包要注意被赋值的变量个数和元组中的值个数相同

组包

a = 1,2,3,4,5
print(a)
print(type(a))

拆包
a1, a2, a3, a4, a5 = a
a1, a2, a3, a4, a5 = [1,2,3,4,5]
a1, a2, a3, a4, a5 = ‘abcde’
a1, a2, a3, a4, a5 = {‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4, ‘e’: 5}
print(a1,a2,a3,a4,a5)

  1. 函数返回多个值

当在函数中,需要返回多个值的情况下,
可以在return 后面直接将多个值写出来
解释器在返回时,会将多个值自动进行组包

def test():
    cl = [1,2,5,9,0,7,3,5,]
    # ma = max(cl)
    # mi = min(cl)
    cl.sort()
    ma = cl[len(cl)-1] # -->mi = cl[0]
    # mi = cl[0]
    mi = cl[0]
    # print(ma,mi)
    return ma,mi

a = (test())
print(a)
  1. 函数嵌套调用及过程

函数嵌套是指,在一个函数的函数体内,又去调用了另外一个函数
如果函数内调用了另一个函数,那么当前函数会中断执行
跳转到另一个函数位置进行执行,被调用执行结束后,
才回到当前函数恢复中断,继续执行
无论函数如何调用: 谁调用函数,被调用函数执行完就返回到谁那去

def a():
    print('a的开始')
    b()
    print('a的函数完事')

def b():
    print('b的开始')
    c()
    print('b的函数完事')

def c():
    print('c的开始')
    print('c的函数完事')

a()

4.函数递归调用
递归调用是一种特殊的嵌套调用
本质就是自己调用自己

求阶乘
 5! = 1 * 2 *3 * 4 * 5
 factorial 阶乘
def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)  #

a = (factorial(5))
print(a)



factorial(5) -> 5 * factorial(4)            -> reutrn 5 * 24  -> 120   # 4*6的值--> 返回到factorial(4)

                -> 4 * factorial(3)         -> return 4 * 6   # 3*2得值 --> 返回到factorial(3)
                
                    -> 3 * factorial(2)     ->  reutrn 3 * 2  # 2*1的值--> 返回到factorial(2)
                    
                        -> 2 * factorial(1)  -> return 2 * 1 # 1--> 返回到factorial(1)
                            
                            -> return 1

全局变量和局部变量

(公共使用)全局变量:
是指定义函数外的变量,不属于任何一个函数,这个变量可以在任何函数中使用.

局部变量:
定义在某个函数中,该变量只在该函数中有效,除该函数外,都不能使用这个变量

如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据 也理解为对全局变量进行修改,而不是定义局部变量
如果在一个函数中需要对多个全局变量进行修改,那么可以使用

num = 100  # 全局变量

def func_a():
    a_num = 200  # 定义一个局部变量
    print(num)
    print(a_num)


def func_b():
    num = 300
    print(num)
    print(num)

变量查找规则
LEGB
Local -> EnClosed -> Global -> Buildins
本地 -> 闭包 -> 全局 -> 内建

func_a()
func_b()

  1. 多个函数间利用全局变量共享数据
    因为全局变量在使用时,特性是共享,所以可以利用全局变量,
    实现函数间的数据通信

全局变量的修改共享
num = 0 # 不可变类型

c_list = [] # 属于可变类型

定义一个用来上传数据的函数

def upoad_data():
global num  # 如果想修改全局变量,需要声明
num = 100
print(num)
c_list.append(1)  # 可变类型的修改时不需要声明的

定义一个用下载数据的函数
def download_data():
print(num,c_list)
测试
download_data()
upoad_data()
download_data()

7.引用
引用就是数据在内存中存储时的内存编号
通过id() 函数可以得到数据在内存的 “地址”

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

8.可变类型和不可变类型
不可变类型:
数字 int
字符串 str
浮点数 float
布尔类型 bool
元组 tuple

特点: 这些数据都是不可以直接修改的,如果在修改或赋值时,都会开辟一个新空间

可变类型:
列表 list
字典 dict
集合 set

特点: 这个些数据类型,是可以直接在原对象上进行修改数据,修改完成后,并不影响原对象**“地址”**
c_l = []
print(id(c_l)) # 假设地址是:1
c_l.append(‘i’)
print(id(c_l),c_l) # 添加数据"i"后地址并没有发生改变

9.默认值参数
在定义函数时,函数中的形式参数,被赋值,这个值就是默认值
当在函数调用时,如果给定了值,那么就使用给定值,如果没有给定值,那就使用默认值

注意:
# 在默认值参数的右侧,不能出现没有默认值的参数,在传递数据时是依次传递的
例:
def display(a,b=0,c): # a c 没有默认值
print(a,b,c)

display(1) # 只给了一个数据 数据传递给了a c 并没有数据,程序运行会报错
display(1,2) # 虽然给了两个数据 数据传递给了a b c还是没有数据,程序运行依然会报错
# 所以在有默认值参数的右侧,不能出现没有默认值的参数,在给参数传递数据时是依次传递的

10位置参数和关键字参数
位置参数—>实参
使用位置参数时,因为类型的原因,那么实参的顺序要和形参的顺序完全一致
当没有默认值的情况下,参数的个数和也要一致

def show(n,s):
    for c in s:
        print("%s--%s" % (n,c))

show(1, 'hello')  #  1对应 n,hello对应 s

关键字参数—>形参
在定义形式参时,每个参数都可以理解成一个key
使用这个key,可以明确的为当前这个参数进行赋值
使用关键字参数,可以忽略参数的顺序问题

def show(n,s):
    for c in s:
        print("%s--%s" % (n,c))

show(s = 'word',n = 2)  #  关键字参数在实参传递给形参时参数的顺序可以改变

11.不定长位置参数
*args 在参数中定义了该形参后,那可以通过 *args 接收多个不确定个数的位置参数

def my_sum(*args):
    print(args)
    s = 0
    for i in args:
        s += i
    print(s)

my_sum(1,2)
my_sum(1,2,3)
my_sum(1,2,3,4)
my_sum(1,2,3,4,5)

12.不定长关键字参数
**kwargs 在参数中定义了该形参后,那可以通过 **kwargs 接收多个不确定个数的关键字参数

重点:
记住这种函数定义格式:当定义函数时,如果函数的参数想接收任意类型和个数,那么定义格式如下:

def 函数名(*args, **kwargs):
	函数体内容
def show(**kwargs):
    print(kwargs)

show(a=1)
show(a=1,b=2)
show(a=1,b=2,c=3)
  1. 混合参数(了解)
    如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的
    在形参中默认有值的参数,称之为缺省参数
    注意:带有默认值的参数一定要位于参数列表的最后面
def func(a, b, c, d, e, *args, f=1, g=2, **kwargs):
    print(a,b,c,d,e)
    print(args)
    print(f,g)
    print(kwargs)


func(1,2,3,4,5)
func(1,2,3,4,5,5,6,7,8,9)
func(1,2,3,4,5,5,6,7,8,9,f=11,g=22)
func(1,2,3,4,5,5,6,7,8,9,f=11,g=22,h=333,i=444)

定义一个可以接收任何参数的函数

def display(*args,**kwargs):
    print(f'args:{args}')
    print(f'kwargs:{kwargs}')


display()
display(1,2,3)
display(a=1,b=2)
display(1,2,3,4,a=1,b=2)

13.可变参数的的二次传递

def show(a,*args,**kwargs):
    print(a)
    # display(args)   #  只把 Argsf 元组赋给a.  b,c,d 三个变量没有值
    print(args)
    print(*args)
    display(args)---> 会报错
    display(*args)  # 手动解包 *args
                     # 当使用*args时,不是将一个元组赋给四个变量
                     # 而是将元组进行解包,将元组中的元素依次赋给四个变量

def display(a,b,c,d):
    print(a,b,c,d)

show(1,2,3,4,4)