3.python基础知识点3

函数

1.初识函数

函数到底是个什么?

函数,一大堆代码,给这一堆的代码再起个名字。

# 定义一个函数
def 函数名()://def hanshu():
    print(123)
    print(123)
    print(123)
    print(123)
    ....

# 执行函数(函数内部代码就会执行)
函数名()
def get_info_data():
    print("欢迎使用xxx")
    v1 = 123
    v2 = 567
    v3 = v1 + v3
    if True:
        print(123)
	else:
        print(999)
	print("END")
    
get_info_data()

了解函数是什么了,那么他的应用场景是什么?

  • 面向过程编码:按照业务逻辑从上到下去累代码。

    • 监控系统,监控公司的电脑。

      print("欢迎使用xx监控系统")
      
      if CPU占用率 > 90%:
          发送报警邮件-10if 硬盘使用率 > 95%:
          发送报警邮件-10if 内容使用率 > 98%:
          发送报警邮件-10
    • 棋牌游戏扎金花

      # 1.生成一副扑克牌6行代码
      
      # 2.洗牌3行代码
      
      # 3.给5个玩家发三张牌 15行代码
      
      # 4.玩家手中牌的大小比较(80行)
      	- 是否是豹子(大小)
          - 是否是同花顺(大小)
          - 是否是同花(大小)
          - 是否是对子(大小)
          - 是否是单点(大小)
      
  • 函数式编程:用函数来写代码。

    • 监控系统,监控公司的电脑【增强代码的重用性】【应用场景1】

      def 发送邮件():
          发送报警邮件-10print("欢迎使用xx监控系统")
      
      if CPU占用率 > 90%:
          发送邮件()
          
      if 硬盘使用率 > 95%:
          发送邮件()
          
      if 内容使用率 > 98%:
          发送邮件()
      
    • 棋牌游戏扎金花,【增强代码的可读性】

      def 发牌():
          ...
          ..
      
      def 是否是豹子():
          ..
          ..
          
      def 是否是同花顺():
          ..
          ..
          
      def 是否是同花():
          ..
          ..
          
      def 是否是对子():
          ..
          ..
          
      def 是否是单点():
          ..
          ..
          
      # 1.生成一副扑克牌6行代码
      
      # 2.洗牌3行代码
      
      # 3.给5个玩家发三张牌 15行代码
      发牌()
      
      # 4.玩家手中牌的大小比较(80行)
      是否是豹子()
      是否是同花顺()
      ...
      

函数应用场景:

  • 反复用到重复代码时,可以选择用函数编程。【增强代码的重用性】
  • 业务逻辑代码太长,可以选择用户函数将代码拆分。【增强代码的可读性】

2.Python代码发邮件

  • 注册邮箱:网易126、163邮箱。

  • 配置
    在这里插入图片描述

    大家需要去获取授权码,通过代码发邮件,再发送邮件时不要告诉我的账号和密码。
    所以,Python代码后续需要使用的:
    	- 账号
    	- 授权码(不是网易邮箱的密码)
    	
    保存好自己的授权码。
    
    SMTP服务器: smtp.163.com
    

    在这里插入图片描述

  • 代码发邮件

    # 1.将Python内置的模块(功能导入)//该文件名不能叫smtplib或者email
    import smtplib
    from email.mime.text import MIMEText
    from email.utils import formataddr
    
    # 2.构建邮件内容
    msg = MIMEText("领导早上好,领导今天辛苦了。", "html", "utf-8")  # 内容,"html", "utf-8"为固定形式
    msg["From"] = formataddr(["xqs", "youxiang@126.com"])  # 自己名字/自己邮箱
    msg['to'] = "888888888@qq.com"  # 目标邮箱
    msg['Subject'] = "360一天"  # 主题
    
    # 3.发送邮件
    server = smtplib.SMTP_SSL("smtp.126.com")
    server.login("youxiang@126.com", "WOAIJWEKAMDJXIF")  # 账户/授权码
    server.sendmail("youxiang@126.com", "888888888@qq.com", msg.as_string())  # 自己邮箱/目标邮箱/内容
    server.quit()
    

3.函数的参数

3.1 基本使用

def 函数名(形式参数1,形式参数2,形式参数3): # 简称形参
    函数内部代码,将形式参数当做是变量来使用。

    
# 执行函数时,传入的值:实际参数(实参)
函数名(1,2,3)
def my_func(a1,a2,a3):
    result = a1 + a2 - a3
    print(result)
    
# 执行函数
my_func(1,4,1)

# 执行函数
my_func(11,14,99)

在执行函数时,传入参数时候一般有两种模式:

  • 位置传参

    def my_func(a1,a2,a3):
        result = a1 + a2 - a3
        print(result)
        
    # 执行函数
    my_func(1,4,1)//my_func(1,2,3)
    
    # 执行函数
    my_func(11,14,99)
    
  • 关键字传参

    def my_func(a1,a2,a3)://my_func(a1 = 1,a2 = 2,a3 = 3)
        result = a1 + a2 - a3
        print(result)
        
    my_func(a1=11,a2=99,a3=10)
    
    my_func(a2=99,a3=10,a1=10)
    
  • 混合使用

    def my_func(a1,a2,a3):
        result = a1 + a2 - a3
        print(result)
    
    # 位置传参在前面,关键字传参是在后面!!!只能位置传参在前,关键字传参在后
    my_func(123,99,a3=10)
    
    my_func(123,a2=99,a3=10)
    

注意:

  • 函数要求传入几个参数,你就要传入几个参数。
  • 参数可以是任意类型:None、bool、int、str、list、dict…

3.2 默认参数

def func(a1,a2,a3):
    pass

func(1,2,3)

在定义函数时,也可以为某个参数设置默认值。

def func(a1,a2=1,a3=123):
    pass

# 位置传参
func(9)//没有传参的时候用默认值
func(9,10)
func(9,10,100)

# 关键字传参
func(a1=9)
func(a1=100,a2=9)
func(a1=100,a2=9,a3=123)

# 注意注意:函数定时设置的默认参数,只能放在最后。

3.3 动态参数

def func(a1,a2,a3=123):
    pass

func(1,2)

# 参数传入的都是有限的个数。
    def func(*a1)://*a1为可以传任意个参数
        # 用户传来的参数统一会被打包成元组
        # a1 = (1,)
        # a1 = (11,22,33)
        # a1 = (11,22,33,"xxxx",True)
        # a1 = (11,22,33,"xxxx",True, [11,22,33],999)
        # a1 = ( [11,22,33,44,55] ,  )
        # a1 = ( (11,22,33),   )
        print(a1)
        
    # 可以通过位置参数的形式传入n个参数。
    func(1)
    func(11,22,33)
    func(11,22,33,"xxxx",True)
    func(11,22,33,"xxxx",True, [11,22,33],999)
    
    func( [11,22,33,44,55] )
    func( (11,22,33) )
    func()
    
  • **

    def func(**dt):**dt为可以传任意个参数
        # 自动将数据打包整字典
        # dt = {"a1":1,"b1":88,"cc":99}
        print(dt)
        
    # 必须用关键字的形式传参
    func(a1=1,b1=88,cc=99)//里面代指参数也传进去
    func(a1=1,b1=88,cc=99)
    func()
    
  • *

    def func(*x1,**dt):
        # x1 = (11,22,3)   dt = {"xx":123,"uu":999, "b12":"root"}
        # x1 = ()    dt = {}
        pass
    
    func(11,22,3, xx=123,uu=999,b12="root")
    func()
    
    # 注意实现
    #   1.定义函数顺序 //只能一个*在前,    *x1,**dt
    #	2.执行函数传参的时,位置传参在前,关键字传参在后。
    #	3.当不传参数时,# x1 = ()    dt = {}空元组,空字典
    
  • 混合之前的使用

    def func(a1,a2,a3,*x1,**dt):
        pass
    
    func(11,22,33,44,55,66,77,a1=123)//a1,a2,a3为11,22,3344,55,66,77,*x1,
    

重点:

  • * 支持传入多个参数,自动会将参数打包成 元组 、字典。

  • 【潜规则】在定义动态参数时,*args、**kwargs

    def func(*args,**kwargs)://*args  **kwargs
        pass
    

4.函数的返回值

  • print,输出,可以在任何的地方使用。
  • 函数的返回值

在以后的开发过程中,定义一个函数,帮助你实现某个功能,希望函数给你产出一个结果。

def func(a1,a2):
    res = a1 + a2
    return res

# 1.执行func函数
# 2.将函数执行的返回值 赋值给data
data = func(100,200)

关于返回值:

  • 返回值可以是任意类型

    def f1():
        return 123
    
    v1 = f1()
    
    def f1():
        return [11,22,33,44]
    
    v1 = f1()
    
    def f1():
        return (11,22,33,44)
    
    v1 = f1()
    
    def f1():
        return 11,22,33  # 返回的是一个元组 (11,22,33)
    
    v1 = f1()
    
  • 函数没有返回值,默认返回None(**)

    def func(a1,a2):
        res = a1 + a2
        
    # data = None
    data = func(100,200)
    
  • 在函数的执行过程中,一旦遇到return,立即结束当前函数的执行并返回值。

    def func():
        v1 = 123
        v2 = 456
        return 999
    	v3 = 180
        
    res = func()
    
    def func():
        for i in range(100):
            return i
        
    res = func() # 0
    
    def func():
        for i in range(100):
            break
        
    res = func() # res = None
    
    def func():
        for i in range(100):
            continue
        
    res = func() # res = None
    
    def func():
        for i in range(100):
            print(i)
        print("END")
    res = func() # 函数返回值 res=None
    
  • 在函数中可以只写return,后面没有值也是返回None

    def func():
        print(1)
        print(2)
        return 
    	print(3)
        
    res = func()
    

5. 函数的调用

def func():
    print(123)
    print(123)
    
func()
func() # 报错

def func():
    print(123)
    print(123)

注意:内存中如果已创建了函数,才可以调用。

def f1():
    print(123)
    
def f2():
    print(456)
    
f1()
f2()
f1()
def f1():
    print(123)
    return 1
    
def f2(arg):
    data = arg + 100
    return data
    
def f3(xx):
    print(xx)
    
v1 = f1()
v2 = f2(v1)
v3 = f3(v2)

# v1= 1
# v2= 101
# v3= None
def f1():
    print(1)
    print(2)
    
def f2():
    print(666)
    f1()
    print(999)
    
f2()
666
1
2
999
def f1():
    print(1)
    print(2)
    
def f2():
    print(666)
    data = f1()
    print(data)
    print(999)
    
f2()
666
1
2
None
999

在数据类型的学习中我们学过可变和不可变类型:

  • 可变类型:列表、字典、集合【独有、公共能时,一般都可以对内部元素进行修改】
  • 不可变类型:字符串、整型、元组、布尔类型

6. 函数参数传递的是内存地址

v1 = "xqs"
v2 = v1

在这里插入图片描述

def func(a1):
    print(a1)

v1 = "xqs"
func(v1)

# 注意:函数在传递参数时,默认不会重新创建一份数据,再赋值给函数中的参数,而是同时指向同一块内存。
# 参数传递是:引用、内存地址。
def func(a1):
    a1.upper()

v1 = "xqshun"
func(v1)

print(v1) # xqshun

注意:a1和v1是同一块内存地址,但由于字符串是不可变类型。a1.upper() 生成新的值。

def func(a1):
    a1.append(666)

v1 = [11,22,33]
func(v1)

print(v1) # [11,22,33,666]

注意:a1和v1是同一块内存地址,但由于列表是可变类型 & append是在原列表中追加数据。

这个意义是不同的,在数产和在城发有本质上的区别,必须要上会之后才能变成数产的实习生,上会这件事数产不急,因为他们不需要实习生

注意事项:

  • 函数传递参数时,默认传递是内存地址/引用(不会重新拷贝一份数据再传递)
  • 一定要注意参数传递是可变/不可变类型; 函数内部执行操作时,是重新生成数据;修改原数据。

7.数据是否会混乱?

def func(a1):
    data = a1 + 100
    print(data)
    
func(100)    func(200)

当我们每次执行一个函数时,都会为此执行的过程创建一块内存(调用栈)。

8.作用域

8.1 作用域基础

  • 作用域,理解成就是一块内存区域,只要在这个区域就可以共享这个区域的数据。
  • 在Python中,执行函数函数,就会为函数创建一个作用域。
  • Python代码只要一运行,就会有一个全局的作用域。
name = "xqs"
# print(age) # 报错、999
age = 999
if True:
    email = "xxx@live.com"
else:
    gender = "男"
    
for i in range(10):
    pass
print(name)
print(age)  # 999
print(email)
print(i)
age = 100
print(age)  # 100

# print(gender) # 报错
name = "xqs"

def func():
    v1 = 100
    v2 = 200
    v3 = v1 + v2
    print(v3)
func()

def f1():
    age = 19
    print(age)
    
def f2():
    print(age)
    
f1()
# f2() # 报错

def f3():
    txt = "我是"
    data = text + name
    print(data)

f3()

def f4():
    txt = "我是"
    name = "李国良"
    data = text + name
    print(data)

f4()

print(name) # "刘光" / "xqs"

# 寻找变量的值时,优先回去自己的作用域中找,自己没有的话,去父级作用域找。
# print(v1) # 报错 / 100 --> 报错。

注意:

  • 在Python中函数是一个作用域。
  • 在作用域中寻找数据时,优先在自己作用域找,自己没有就去上级作用域找。

8.2 关于变量

  • 全局变量,在非函数中定义的(py文件顶层)
  • 局部变量,在函数中定义的变量。

潜规则:定义全局变量时,要用大写,多个单词用下划线连接。

# 全局变量
NAME = 123
if 1 == 1:
    # 全局变量
    AGE = 18

def func():
	# 局部变量
    data = 999

8.3 global关键字

global是用在函数中,用于表示此变量不是新创建的数据,而是全局变量中的那个数据(地址指向相同)。

关键:

  • 内部global之后,变量就是全局变量。

  • 赋值操作

    NAME = "xqs"
    NAME = "张"
    

    动态

核心要领
  • 找变量,优先在自己作用域找,自己没有就去上一级找。

  • 【无global关键字】全局变量和局部变量重名时,自己内部创建的变量,与全部无关

    name = "xqs"
    
    def info():
        name = "root"
        print(name)
        
    print(name)
    info()
    print(name)
    
  • 【有global关键字】全部变量和局部变量重名时,所有的都是全局变量。

    name = "xqs"
    
    def info():
        global name
        name = "root"
        print(name)
        
    print(name)
    info()
    print(name)
    

9.函数名就是变量名

name = "xqs"
age = 18
def func():
    print(123)
    print(456)
    
func = 123
print(func) # 123
v1 = "xqs"
v2 = v1

print(v2) # "xqs"
def func():
    print(123)
    return 111

data = func()
def func():
    print(123)
    print(123)
    print(123)
    
v1 = func
v2 = func()
v3 = v1()
# v1 = 函数func
# v2 = None
# v3 = None

本质上:func就是一个变量,代指这个函数而已, func() -> 执行函数。

在Python的列表中可以存放各种数据类型:

data = [11,22,True,"xxx",(11,223),{},]
def func():
    return 123

v1 = 999

data_list = [1,2,"xqs",v1, func, func, func, func(), func() ]

data_list[4] # 函数
m1 = data_list[4]()

data_list[5] # 函数
m2 = data_list[5]()

data_list[6] # 函数
m3 = data_list[6]()

data_list[7] # 123
data_list[8] # 123

10. lambda表达式(匿名函数)

在特定情况下,让我们的代码更简洁。

lambda表达式(匿名函数),我一行代码实现定义简单的函数。

def func():
    return 123


# func是函数名(变量)
# lamdab : 函数体,函数体中写了123,内部自动会执行一个return
func = lambda : 123

res = func()
print(res) # 123
def func(a1,a2):
    return a1 + a2

func = lambda a1,a2 : a1 + a2
res = func(100,200)
print(res) # 300
def func(data_string):
    return data_string.upper()

func = lambda data_string : data_string.upper()
res = func("root")
print(res) # "ROOT"
def func(data_list):
    return data_list[0]

func = lambda data_list : data_list[0]
res = func([11,22,33,44])
print(res) # 11

注意注意注意:

  • lambda内部自动return
  • return后面到底生成的是什么?返回的就是什么。
data = []
v1 = data.append(123)  # None,append是python内部定义的函数,执行函数,内部没有返回值。
v2 = data.append(1456) # None
def func(data_list):
    return data_list.append(999)

res = func([11,22,33])
print(res) # None
func = lambda data_list : data_list.append(123)

value = func([11,22,33])
print(value) # None

11. 函数做参数

def do():
    print("do")

def func(a1,a2):
    print(a1)
    a2()

func( 11 , do )
11
do

注意:一般情况下少用。

def do():
    print("do")

def func(a1,a2):
    print(a1)
    res = a2()
    print(res)
    return 123

v1 = func( 11 , do )
print(v1)
11
do
None
123

12.内置函数

Python内部为我们已写好的函数,我们可以直接拿来用,不需要自己再编写了。

data = abs(-10)
print(data)
abs = 123123

data = abs(-10) # 报错

12.1 第1组(5)

  • abs,绝对值

    data = abs(-10)
    print(data) # 10
    
  • pow,次方

    data = pow(2,5)   # 获取2的5次方
    print(data)
    
  • sum,求和

    num_list = [1,2,10,20]
    res = sum( num_list )
    print(res) # 求和
    
  • divmod,商和余数

    v1,v2 = divmod(92,10)
    print(v1) # 9
    print(v2) # 2
    
  • round,保留小数点后几位

    data = round(3.14134,2)
    print(data) # 3.14
    

12.2 第2组(4)

  • min,求最小值

    data = [11,22,-19,99,10]
    res = min(data)
    print(res)
    
  • max,求最大值

    data = [11,22,-19,99,10]
    res = max(data)
    print(res)
    
  • all,是否所有元素转换成布尔值都是True

    data = [1,-1,88,9]
    v1 = all(data)
    print(v1) # True
    
    data = [1,-1,88,0,9]
    v1 = all(data)
    print(v1) # False
    
    data = [1,-1,88,"",9]
    v1 = all(data)
    print(v1) # False
    
    v1 = input("用户名:")
    v2 = input("密码:")
    is_valid = all( [v1,v2] )
    if is_valid:
        print("都不为空")
    else:
        print("用户名或密码为空")
    
  • any,只要有转换为布尔值为True

    data = [1,-1,88,9]
    v1 = any(data)
    print(v1) # True
    
    data = [1,-1,88,0,9]
    v1 = any(data)
    print(v1) # True
    
    data = [0,"",[],{}]
    v1 = any(data)
    print(v1) # False
    

12.3 第3组(3个)

  • bin,十进制转换成二进制

    res = bin(100)
    print(res) # 0b101001001
    
  • oct,十进制转换成八进制

    res = oct(100)
    print(res) # 0o1221
    
  • hex,十进制转换成十六进制

    res = hex(100)
    print(res) # 0x1221
    

12.4 第4组(2)

编码时 unicode ,将文字和二进制做上对应。

A        101010101010                   65
徐		101111110010000                24464
  • ord

    v1 = ord("A")
    print(v1) # 65
    
  • chr

    v2 = chr(65)
    print(v2) # "A"
    

基于chr实现动态验证码:

# 1.随机获取 65 - 90 的数字,就可以将chr转换成字母。
import random

num = random.randint(65,90)
print(num)
char = chr(num)
print(char)
import random

char_list = []

for i in range(6):
    num = random.randint(65, 90)
    char = chr(num)
    char_list.append(char)

print(char_list)  # ['P', 'L', 'N', 'E', 'L', 'G']

code = "".join(char_list)
print(code)

12.5 第5组(9)

  • int

  • str

    data = str(10)
    print(data)
    
  • bool

  • list

  • dict

  • set

  • tuple

  • float

  • bytes

12.6 第6组(10)

  • len

  • print

  • input

  • open

    f = open("xxx",mode='r',encoding='utf-8')
    data = f.read()
    f.close()
    
  • range

  • hash,计算哈希值(字典的键、集合元素都必须是可哈希)

    data = hash("xqs")
    print(data)
    
  • type,查看数据类型

    def func(data):
        # 如果data是字符串则返回123
        # 如果data是列表则返回456
        # 其他的返回None
        if type(data) == str:
            return 123
        elif type(data) == list:
            return 456
        else:
            return None
    
    v1 = func(123123)
    
    print(v1)
    
  • callable,是否可执行(后面是否可以加括号执行)

    name = "xqs"
    
    v1 = callable(name)
    print(v1) # False
    
    def func():
        print(666)
        
    v2 = callable(name)
    print(v2) # True
    
    def func():
        return 123
    
    data_list = [11,22,33, func ]
    # 循环每个元素,如果可以执行则执行并获取返回值
    for item in data_list:
        if callable(item):
            res = item()
            print(res)
    	else:
            print(item)
    
  • enumerate,循环过程中,自动提供自增的一列。

    goods = ["飞机", "迫击炮", "AK47"]
    
    # 以前
    # for i in range(len(goods)):
    #     msg = "{} {}".format(i + 1, goods[i])
    #     print(msg)
    
    # 现在
    for idx, item in enumerate(goods, 100):
        msg = "{} {}".format(idx, item)
        print(msg)
    
  • sorted,排序 (不修改原数据、生成新的列表)

    # 列表中的排序(原列表进行排序)
    data_list = [11,22,33,44,55,1,-10]
    data_list.sort()
    print(data_list)
    
    data_list = [11,22,33,44,55,1,-10]
    new_data = sorted(data_list)
    print(new_data)
    

    注意:如果是元素是中文如何排序?

    data_list = ["1", "2", "3", "10", "12"]
    new_data = sorted(data_list)
    
    # ['1', '10', '12', '2', '3']
    print(new_data)
    

13. 推导式

Python中为我们提供的一个简便的语法,一行代码实现生成列表、字典等多个元素。

创建一堆数据并存储到列表中:

data = [] # [1,2,3,4,5...100]
for i in range(1,101):
    data.append(i)
user_list = []
for i in range(1,301):
    user = "工号-{}".format(i)
    user_list.append(user)

13.1 列表推导式

# data_list = [ 0,1,2,3,4,..99 ]

data_list = [ i for i in range(100)  ]
# data_list = [ 100, 100, 100,100,100..100 ]

data_list = [ 100 for i in range(100)  ]
# data_list = [100,101,102...199 ]

data_list = [ 100 + i  for i in range(100)  ]
# data_list = [ [1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2], ]
data_list = [ [1,2]  for i in range(100)  ]
# data_list = [ (0,100), (1,101),....(99,199) ]
data_list = [ (i,i+100)  for i in range(100)  ]
# data_list = [ "工号-0","工号-1","工号-2","工号-3",..."工号-99", ]
data_list = [ "工号-{}".format(i)  for i in range(100)  ]
# [7,8,9]
data_list = [ i for i in range(10) if i > 6  ]
# [7,8,9]
data_list = [ i for i in range(100) if i > 6 and i<10 ]

13.2 字典推导式

"""
data = {
    0:123,
    1:123,
    ...
    9:123,
}
"""
data = { i:123 for i in range(10) }
"""
{
	0:(0,100),
	1:(1,100),
}
"""
data = { i:(i,100) for i in range(10) }
"""
{
	8:(8,100),
	9:(9,100),
}
"""
data = { i:(i,100) for i in range(10) if i > 7}

总结

上述就是学习函数必备的知识点。

  • 定义

  • 执行

  • 参数

  • 返回值

  • 作用域

  • 函数是一个变量

    def func():
    	pass
    
  • lambda 表达式

  • 内置函数

    内置函数:python内部给我们提供好的函数。
    自定义函数:
            def func():
                pass
    
  • 推导式(与函数无关),简化代码创建字典、列表。

14. 关于pip.exe

下载视频时,用到了pip去下载第三方包。

pip是一个专门用于帮助去下载第三方包的工具,安装好Python之后,自动安装好了。

C:\python39	
	- python.exe      Python解释器
	- Scripts
		- pip.exe	  包管理工具
	- Lib(内置+第三方)
		- site-package
			- 第三方包
>>>C:\python39\python.exe /Users/xqs/PycharmProjects/gx_day06/demo.py
>>>C:\python39\Scripts\pip.exe  install  包

14.1 系统的环境变量

如果你将:C:\python39\Scripts 添加到了环境变量中。

>>>pip install 包名称

在这里插入图片描述

14.2 常见命令

  • 安装

    pip install 包名称
    
  • 卸载

    pip uninstall 包名称
    
  • 罗列目前已安装第三方包

    pip list
    
  • 将已安装的包写入到文件中

    pip freeze > a1.txt
    
    pip freeze > requirements.txt
    
    在自己电脑上安装(逐一安装)
    	pip install beautifulsoup4==4.9.3
    	pip install certifi==2020.12.5
    批量安装:
    	pip install -r requirements.txt
    

问题:

  1. 在同一个Python的环境中,无法通知安装多个版本的包,只能同时有一个。
  2. requirements.txt 一般放在项目的根目录录下(每个项目根目录下都要放一个)。

14.3 配置

在这里插入图片描述

如何成为开源作者,发布包:
https://www.bilibili.com/video/BV17541187de

有时在进行下载时,会发现速度比较慢:

pip install 包
timeout/retry...

在这里插入图片描述

基于豆瓣源去下载某些第三方包:

  • 一次性操作

    pip install flask  -i  https://pypi.douban.com/simple/ 
    pip install django  -i  https://pypi.douban.com/simple/ 
    
  • 永久默认豆瓣

    pip config set global.index-url https://pypi.douban.com/simple/
    
    pip install django
    

    在这里插入图片描述

14.4 源码安装

一般情况下,我们在开发过程用到的所有的第三方包都可以通过 pip 管理工具来进行安装,但是如果你遇到一些包在pip中没有,可以找到他的源码,也可以通过源码安装。

  • 下载源码

    https://pypi.org/project/requests/#files
    
  • 解压
    在这里插入图片描述

  • 安装【终端】

    • 进入源码目录

    • 执行安装命令

      python3.9 setup.py build
      python3.9 setup.py install
      

14.5 wheel包

有些源码开发者,提前把代码打包成 wheel包,你以后下载时,就不需要自己build,直接安装即可。

  • pip 支持wheel包的安装了。

    pip install wheel
    
  • 下载wheel包
    在这里插入图片描述

  • 进入终端去安装

    • 打开终端,进入wheel包目录

    • 直接去安装

      pip3 install mysqlclient-2.0.3-cp39-cp39-win_amd64.whl
      

注意事项:无论你是通过什么方式安装的第三方包,都是安装在了 site-package 目录。

C:\python39	
	- python.exe      Python解释器
	- Scripts
		- pip.exe	  包管理工具
	- Lib(内置+第三方)
		- site-package
			- 第三方包

想要卸载的话,直接通过:pip uninstall 包

模块和包

什么是模块和包呢?

  • 模块,就是指py文件,我们可以将一些功能按照某个中维度划分。

    自定义
    内置
    第三方
    
  • 包,就是指文件夹,我们可以将一些功能按照某个中维度划分。

    里面包含多个py文件。
    

一般情况下,大家平时的讨论和沟通时,一般都统称为:模块。

接下来我们要学习模块和包时:

  • 自定义模块和包 + 使用
  • 常见内置模块 + 使用
  • 第三方模块 + 使用

1. 自定义模块和包

1.1 快速上手

gx_day07
├── app.py
└── utils.py
# app.py

# 1.导入utils模块
import utils

choice = input("请输入序号:")

# 2.调用utils模块中的str_to_int功能。
res = utils.str_to_int(choice)
if res == None:
    print("输入错误")
else:
    msg = "序号是:{}".format(res)
    print(msg)

# utils.py
def str_to_int(str_data):
    """
    字符串转换为整形
    :param str_data: 要转换的字符串
    :return: 整形 or None(无法转换)
    """
    if str_data.isdecimal():
        return int(str_data)
    return None

def f1():
    pass

def f2():
    pass

1.2 关于模块和包的导入路径

在实际案例中,包和模块一般都放在:

  • 运行文件所在的同级目录。【导入成功】
  • 模块和包在Python的安装目录。【导入成功】

如果我想要把某个模块放在 F:\code\hello.py,导入到我的项目里来,默认一定是无法导入的,这是因为Python内部在看待 import xxx 自动回去某一些目录中寻找。

import hello
import sys
print(sys.path)

[
    '/Users/xqs/PycharmProjects/gx_day07', 
    '/Users/xqs/PycharmProjects/gx_day07', 
    '/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_display', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/requests-2.26.0-py3.9.egg', 
    
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/charset_normalizer-2.0.7-py3.9.egg', 
  '/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_matplotlib_backend']

以上只是了解后,如果你需要让python导入模块是去自定定义的目录中寻找,那么你就需要:

import sys

# 1.自定义文件所在的目录添加到sys.path
sys.path.append(r"F:\code")

# 2.导入
import hello

问题:sys.path获取到的是个什么?

import xx
是个列表,列表是有序。

[
    '/Users/xqs/PycharmProjects/gx_day07', 
    '/Users/xqs/PycharmProjects/gx_day07', 
    '/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm_display', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip', 
    '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9', 
]

注意:千万不要让自己的模块名称和python内置模块的名称同名(此时你想去调用Python内置的模块中的功能时,无法调用)。

在这里插入图片描述

1.3 关于模块和包的导入方式

1.3.1 import导入
  • 导入一个py文件。
import utils
utils.u_f1()

import commons.pager
commons.pager.p_1()
1.3.2 from导入
  • 导入级别:py文件中的函数
  • 导入级别:导入一个py文件
from utils import u_f1
u_f1()

from commons.pager import p_1
p_1()

from commons import pager
pager.p_1()
from commons.pager import p_1, p_2, p_3
from commons.pager import *

p_1()
p_2()
p_3()
p_4()
from commons.pager import p_1 as p2

def p_1():
    return "ppppp"

p_1()
p2()
import 和 from 两种方式都是导入模块,效果上相同。一般情况下:
- 多个层级
	from commons.xxx.xxx import sdf
- 单层目录(与运行的py文件在同级目录)
	import xx

小节

  • sys.path

    import sys
    sys.path.append(".....")
    
    import xx
    
  • 自己的模块不要内置的重名。

  • 导入的方式:import / from xx import xxx

2.常见的内置模块

Python内部提供好的功能。

2.1 hashlib

是一个对数据进行加密的模块。

import hashlib

data = "admin"
obj = hashlib.md5()
obj.update(data.encode('utf-8'))
res = obj.hexdigest()
print(res)

在以后咱们开发项目时,密码不要用明文存储。

xqs,21232f297a57a5a743894a0e4a801fc3

为了防止数据库泄露,用户名和密码全都泄露。

2.1.1 密文匹配(不能反解)

MD5加密,不可反解。

admin    ->   21232f297a57a5a743894a0e4a801fc3

案例:以后登录时候要进行密文匹配。

user_dict = {
    "xqs":"21232f297a57a5a743894a0e4a801fc3"
}

user = input("用户名:") # xqs
pwd = input("密码:") # admin

db_pwd = user_dict.get(user) # 21232f297a57a5a743894a0e4a801fc3
# 将 pwd 进行加密的到密文:21232f297a57a5a743894a0e4a801fc3
2.1.2 撞库

在这里插入图片描述

有些人搞一些机器跑,把明文的密文跑。

admin	adfasdfasdfasdf
123		asdfadfasdfasdfasdf
ffsdf   asdfadfasdfasdfasdf
2.1.3 加盐
import hashlib

data = "admin"

salt = "asidfjaksdkjasdiuofiqjskda91qw3asdf"
obj = hashlib.md5(salt.encode('utf-8'))
obj.update(data.encode('utf-8'))
res = obj.hexdigest()
print(res) # c06b63d965921fe0a8803071b623e4e9

2.2 random

帮助我们生成一些随机数据。

import random

v1 = random.randint(1, 20)  # 大于等于1; 小于等于20
print(v1)

random模块中的其他常用功能:

import random

# 1.获取随机的整数
v1 = random.randint(1, 20)  # 大于等于1; 小于等于20
print(v1)

# 2.获取随机的小数
v2 = random.uniform(1, 10)
print(v2)

# 3.随机抽取1个数
data_list = [11, 22, 33, 44, 55]
v3 = random.choice(data_list)
print(v3)

# 4.随机抽取多个数
data_list = [11, 22, 33, 44, 55]
v4 = random.sample(data_list, 3)
print(v4)

# 5.打乱顺序
num_list = [i for i in range(100)]
random.shuffle(num_list)
print(num_list)

2.3 json

本质上:是一种数据格式,字符串形式。

用处:让不同编程语言之间实现数据传输。

在这里插入图片描述

JSON格式:

  • 外部整体大的字符串

  • json字符串的内部如果有字符串的话,一定需要用双引号。

  • json字符串中不会存在python中的元组那样的格式。

    info = {'k1':123,'k2':(11,22,33,44)}
    
    JSON格式:
    	'{"k1":123,"k2":[11,22,33,44] }'
    

以下哪些数据是JSON格式的字符串:

v1 = '{"k1":123,"k2":456}'
v2 = "{'k1':123,'k2':456}"
v3 = '{"k1":123,"k2":456,"k3":[11,22,33]}'
v4 = '{"k1":123,"k2":456,"k3":(11,22,33)}'
import json

info = {'k1': 123, 'k2': (11, 22, 33, 44)}

# python的数据类型转换为JSON格式的字符串
res = json.dumps(info)
print(res) # '{"k1": 123, "k2": [11, 22, 33, 44]}'
import json

data_string = '{"k1": 123, "k2": [11, 22, 33, 44]}'

# 将JSON格式的字符串转换为Python的数据类型
res = json.loads(data_string)
print(res)

print(res['k1'])
print(res['k2'])
print(res['k2'][-1])

问题:JSON字符串和普通的字符串有什么区别?

v1 = "asdfasdkfasdfasd"
v2 = "[11,22,33]"

问题:

v1 = "(3,6)"   # 是JSON格式的字符串吗?

在这里插入图片描述

2.3.1 关于中文
import json

info = {"name": "邱恩婷", "age": 19}

v1 = json.dumps(info, ensure_ascii=False)
print(v1) # {"name": "邱恩婷", "age": 19}
2.3.2 序列化

在Python中默认只能通过json模块序列化基本的数据类型。

    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+
# 可以序列化(执行正确)
import json
import decimal
info = {"name": "邱恩婷", "age": 19.5, 'f': True, "hobby": None}
v1 = json.dumps(info, ensure_ascii=False)
print(v1)

在这里插入图片描述

import json
import decimal

data = decimal.Decimal("0.3")
res = float(data)

info = {"name": "邱恩婷", "age": 19.5, 'f': True, "hobby": None, "data": res}

v1 = json.dumps(info, ensure_ascii=False)
print(v1)

2.4 time

import time

# 1.获取当前的时间戳 (自1970年1月1日开始)
v1 = time.time()
print(v1)  # 1636956070.0133471 / 1636956095.6416771

案例:

import time

start_time = time.time()

...
....

end_time = time.time()

interval = end_time - start_time
print(interval)
import time

# 1.获取当前的时间戳 (自1970年1月1日开始)
# v1 = time.time()
# print(v1)  # 1636956070.0133471 / 1636956095.6416771

# 2.停止N秒,再继续运行
while True:
    print(1)
    time.sleep(1)

2.5 datetime

  • 时间戳。

    import time
    v1 = time.time()
    
  • datetime格式

    import datetime
    
    v1 = datetime.datetime.now()
    print(v1)  # datetime类型
    
  • 字符串格式

    import datetime
    
    ctime_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(ctime_string)
    
2.5.1 时间转换

在这里插入图片描述

  • 字符串 -> datetime类型

    from datetime import datetime
    text = "2021-11-11"
    res = datetime.strptime(text, "%Y-%m-%d")
    print(res,type(res))
    
  • datetime -> 字符串

    from datetime import datetime
    
    dt = datetime.now()
    res = dt.strftime("%Y-%m-%d-%H-%M")
    print(res)
    
  • 时间戳 -> datetime类型

    import time
    from datetime import datetime
    
    ctime = time.time()
    
    dt = datetime.fromtimestamp(ctime)
    print(dt, type(dt))
    
  • datetime类型 -> 时间戳

    from datetime import datetime
    
    v1 = datetime.now()
    res = v1.timestamp()
    print(res)
    
2.5.2 datetime类型的意义
from datetime import datetime, timedelta

v1 = datetime.now()
# res = v1 + timedelta(days=280)
# print(res, type(res))

res = v1 + timedelta(days=10, hours=20, minutes=10, seconds=100)
# print(res, type(res))

date_string = datetime.strftime(res, "%Y-%m-%d-%H-%M")
print(date_string)

很方便的可以帮我们处理时间加减。

2.6 os

  • 路径的拼接

    window系统:  C:\xx\xxx\xxx
       Mac系统:  /user/xxx/xxx/xxx
     Linux系统:  /user/xxx/xxx/xxx
    
    import os
    
    path = os.path.join("x1","x2","x3","x4",'log.txt')
    print(path) # x1/x2/x3/x4/log.txt 
    
  • 找到上级目录

    import os
    
    file_path = "x1/x2/x3/x4"
    
    # 找到当前路径的上一级目录
    v1 = os.path.dirname(file_path)
    print(v1) # x1/x2/x3
    
  • 绝对路径

    绝对路径:
    	/Users/xqs/PycharmProjects/gx_day07/2021-11-15-15-10.txt
    相对路径(当前执行的程序)
    	见下图
    

    在这里插入图片描述

    如何生成一个绝对路径。

    import os
    
    res = os.path.abspath("xx")
    
    # 当前程序所在目录                             相对目录
    # /Users/xqs/PycharmProjects/gx_day07/   xx
    print(res)
    
  • 判断路径是否存在

    import os
    
    res = os.path.exists(file_path)
    print(res) # True/False
    
    import os
    
    # files/db.txt
    file_path = os.path.join('files', 'db.txt')
    
    # 判断路径是否存在
    if os.path.exists(file_path):
        # 读取文件时,如果文件不存在就会报错:FileNotFoundError
        f = open(file_path, mode='r', encoding='utf-8')
        data = f.read()
        f.close()
        print(data)
    else:
        print("文件不存在")
    
  • 创建文件夹

    import os
    
    path = os.path.join('db', '2021', '11月份')
    print(path)  # db/2021/11月份
    
    os.makedirs(path)
    
    
    import os
    
    #  path = "db/2021/11月份"
    path = os.path.join('db', '2021', '11月份')
    
    if not os.path.exists(path):
        # 创建目录
        os.makedirs(path)
    
  • 删除文件、文件夹

    import os
    
    path = os.path.join('db', '2021', '11月份', 'log.txt')
    
    # 删除文件
    os.remove(path)
    
    import os
    import shutil
    
    path = os.path.join('db', '2021')
    
    # 删除文件夹
    shutil.rmtree(path)
    
  • 判断是否是文件夹

    import os
    
    path = os.path.join('db', 'a1.txt')
    res = os.path.isdir(path)
    print(res)
    
  • os.listdir/os.walk

    import os
    
    # 查看某个目录下的所有的文件和文件夹(一级目录)
    for item in os.listdir("/Users/xqs/Documents/Python/mp4/开篇"):
        print(item)
        
    """
    03 开篇:学习方法的建议.mp4
    .DS_Store
    02 开篇:授课模式须知.mp4
    课堂笔记
    05 开篇:写在最后.mp4
    04 开篇:笔记和文档的编写.mp4
    01 开篇:讲师和课程内容介绍.mp4
    """
    
    import os
    
    # 查看某个目录下的所有的文件和文件夹
    for in_path, folder_list, name_list in os.walk("/Users/xqs/Documents/Python/mp4/开篇"):
        for name in name_list:
            abs_path = os.path.join(in_path, name)
            print(abs_path)
    

各位小伙伴想要博客相关资料的话关注公众号:chuanyeTry即可领取相关资料!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值