• Python-基础学习-第二轮


    数据类型

    Python 默认拥有以下内置数据类型:

    文本类型:str
    数值类型:intfloatcomplex
    序列类型:listtuplerange
    映射类型:dict
    集合类型:setfrozenset
    布尔类型:bool
    二进制类型:bytesbytearraymemoryview

    在 Python 中,当您为变量赋值时,会设置数据类型:

    示例数据类型
    x = "Hello World"str
    x = 29int
    x = 29.5float
    x = 1jcomplex
    x = ["apple", "banana", "cherry"]list
    x = ("apple", "banana", "cherry")tuple
    x = range(6)range
    x = {"name" : "Bill", "age" : 63}dict
    x = {"apple", "banana", "cherry"}set
    x = frozenset({"apple", "banana", "cherry"})frozenset
    x = Truebool
    x = b"Hello"bytes
    x = bytearray(5)bytearray
    x = memoryview(bytes(5))memoryview

    如果希望指定数据类型,则您可以使用以下构造函数:

    示例数据类型
    x = str("Hello World")str
    x = int(29)int
    x = float(29.5)float
    x = complex(1j)complex
    x = list(("apple", "banana", "cherry"))list
    x = tuple(("apple", "banana", "cherry"))tuple
    x = range(6)range
    x = dict(name="Bill", age=36)dict
    x = set(("apple", "banana", "cherry"))set
    x = frozenset(("apple", "banana", "cherry"))frozenset
    x = bool(5)bool
    x = bytes(5)bytes
    x = bytearray(5)bytearray
    x = memoryview(bytes(5))memoryview

    文件

    open函数的参数

    要读写文件,首先要通过内置函数open 打开文件,获得文件对象。

    函数open的参数如下

    1. open(
    2. file,
    3. mode='r',
    4. buffering=-1,
    5. encoding=None,
    6. errors=None,
    7. newline=None,
    8. closefd=True,
    9. opener=None
    10. )

    其中下面这3个参数是我们常用的。

    • 参数 file

      file参数指定了要打开文件的路径。

      1. 可以是相对路径,比如 ‘log.txt’, 就是指当前工作目录下面的log.txt 文件,
      2. 也可以是绝对路径,比如 ’d:\project\log\log.txt',
    • 参数 mode

      mode参数指定了文件打开的 模式 ,打开文件的模式,决定了可以怎样操作文件。

      常用的打开模式有

      • r 只读文本模式打开,这是最常用的一种模式
      • w 只写文本模式打开
      • a 追加文本模式打开

      如果我们要 读取文本文件内容到字符串对象中 , 就应该使用 r 模式。

      我们可以发现mode参数的缺省值 就是 ‘r’ 。

      就是说,调用open函数时,如果没有指定参数mode的值,那么该参数就使用缺省值 ‘r’,表示只读打开。

      如果我们要 创建一个新文件写入内容,或者清空某个文本文件重新写入内容, 就应该使用 ‘w’ 模式。

      如果我们要 从某个文件末尾添加内容, 就应该使用 ‘a’ 模式。

    • 参数 encoding

      encoding 参数指定了读写文本文件时,使用的 字符编解码 方式。

      调用open函数时,如果传入了encoding参数值:

      1. 后面调用write写入字符串到文件中,open函数会使用指定encoding编码为字节串;
      2. 后面调用read从文件中读取内容,open函数会使用指定encoding解码为字符串对象

      如果调用的时候没有传入encoding参数值,open函数会使用系统缺省字符编码方式。 比如在中文的Windows系统上,就是使用cp936(就是gbk编码)。

      建议大家编写代码 读写文本文件时,都指定该参数的值。

    1. if __name__ == '__main__':
    2. # 指定编码方式为 utf8
    3. f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'w', encoding='utf8')
    4. # write方法会将字符串编码为utf8字节串写入文件
    5. f.write('李嘉图:祝大家学有所成!')
    6. # 文件操作完毕后, 使用close 方法关闭该文件对象
    7. f.close()
    8. # 指定编码方式为utf8
    9. f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'r', encoding='utf8')
    10. # read 方法会在读取文件中的原始字节串后, 根据上面指定的gbk解码为字符串对象返回
    11. content = f.read()
    12. # 文件操作完毕后, 使用close 方法关闭该文件对象
    13. f.close()
    14. # 通过字符串的split方法获取其中用户名部分
    15. name = content.split(':')[0]
    16. print(name)

    with

    1. if __name__ == '__main__':
    2. f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'w', encoding='utf8')
    3. f.write('李嘉图:祝大家学有所成!')
    4. f.close()
    5. with open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'r', encoding='utf8') as f:
    6. linelist = f.readlines()
    7. for line in linelist:
    8. print(line)

    附加:文件和目录

    文件和目录操作 | 白月黑羽

    自调用其他程序

    Python中调用外部程序主要是通过两个方法实现的, 一个是os库的 system 函数,另外一个是 subprocess 库。

    os.system函数

    使用os库的 system 函数 调用其它程序 是非常方便的。就把命令行内容 作为 system 函数的参数 即可

    1. import os
    2. if __name__ == '__main__':
    3. os.system('cd D:/test && mkdir test.txt')

    os.system 函数调用外部程序的时候, 必须要等被调用程序执行结束, 才会接着往下执行代码。 否则就会一直等待

    os.system 函数没法获取 被调用程序输出到终端窗口的内容。 如果需要对被调用程序的输出信息进行处理的话, 可以使用 subprocess 模块。

    os.startfile 函数

    如果我们想达到类似文件浏览器双击打开一个文件的效果可以使用 os.startfile 函数。

    这个函数的参数可以是任何 非可执行程序 文件

    os.startfile('d:\\统计数据.xlsx')
    

    可以调用该xlsx对应的关联程序(Excel)来打开该文件。

    subprocess 模块

    Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。

    线程和进程

    创建新线程

    1. # 从 threading 库中导入Thread类
    2. from threading import Thread
    3. from time import sleep
    4. # 定义一个函数,作为新线程执行的入口函数
    5. def threadFunc(arg1, arg2):
    6. print('子线程 开始')
    7. print(f'线程函数参数是:{arg1}, {arg2}')
    8. sleep(5)
    9. print('子线程 结束')
    10. if __name__ == '__main__':
    11. print('主线程执行代码')
    12. # 创建 Thread 类的实例对象
    13. thread = Thread(
    14. # target 参数 指定 新线程要执行的函数
    15. # 注意,这里指定的函数对象只能写一个名字,不能后面加括号,
    16. # 如果加括号就是直接在当前线程调用执行,而不是在新线程中执行了
    17. target=threadFunc,
    18. # 如果 新线程函数需要参数,在 args里面填入参数
    19. # 注意参数是元组, 如果只有一个参数,后面要有逗号,像这样 args=('参数1',)
    20. args=('参数1', '参数2')
    21. )
    22. # 执行start 方法,就会创建新线程,
    23. # 并且新线程会去执行入口函数里面的代码。
    24. # 这时候 这个进程 有两个线程了。
    25. thread.start()
    26. # 主线程的代码执行 子线程对象的join方法,
    27. # 就会等待子线程结束,才继续执行下面的代码
    28. thread.join()
    29. print('主线程结束')

    共享数据的访问控制

    1. from threading import Thread, Lock
    2. from time import sleep
    3. bank = {
    4. 'count': 0
    5. }
    6. bankLock = Lock()
    7. # 定义一个函数,作为新线程执行的入口函数
    8. def deposit(theadidx, amount):
    9. # 操作共享数据前,申请获取锁
    10. bankLock.acquire()
    11. balance = bank['count']
    12. # 执行一些任务,耗费了0.1
    13. sleep(0.1)
    14. bank['count'] = balance + amount
    15. print(f'子线程 {theadidx} 结束')
    16. # 操作完共享数据后,申请释放锁
    17. bankLock.release()
    18. if __name__ == '__main__':
    19. theadlist = []
    20. for idx in range(10):
    21. thread = Thread(target=deposit,
    22. args=(idx, 1)
    23. )
    24. thread.start()
    25. # 把线程对象都存储到 threadlist中
    26. theadlist.append(thread)
    27. for thread in theadlist:
    28. thread.join()
    29. print('主线程结束')
    30. print(f'最后我们的账号余额为 {bank["count"]}')

    deamon线程

    1. from threading import Thread
    2. from time import sleep
    3. def threadFunc():
    4. sleep(1)
    5. print('子线程 结束')
    6. if __name__ == '__main__':
    7. # thread = Thread(target=threadFunc)
    8. # thread.start()
    9. # print('主线程结束')
    10. thread = Thread(target=threadFunc,
    11. daemon=True # 设置新线程为daemon线程
    12. )
    13. thread.start()
    14. print('daemon主线程结束')

    多线程

    Python 官方解释器 的每个线程要获得执行权限,必须获取一个叫 GIL (全局解释器锁) 的东西。

    这就导致了 Python 的多个线程 其实 并不能同时使用 多个CPU核心。

    所以如果是计算密集型的任务,不能采用多线程的方式。

    1. from threading import Thread
    2. def f():
    3. while True:
    4. b = 53*53
    5. if __name__ == '__main__':
    6. plist = []
    7. # 启动10个线程
    8. for i in range(10):
    9. p = Thread(target=f)
    10. p.start()
    11. plist.append(p)
    12. for p in plist:
    13. p.join()

    多个CPU核心的运算能力,可以使用Python的多进程库。

    1. from multiprocessing import Process
    2. def f():
    3. while True:
    4. b = 53*53
    5. if __name__ == '__main__':
    6. plist = []
    7. for i in range(2):
    8. p = Process(target=f)
    9. p.start()
    10. plist.append(p)
    11. for p in plist:
    12. p.join()
    1. from multiprocessing import Process, Manager
    2. from time import sleep
    3. def f(taskno, return_dict):
    4. sleep(1)
    5. # 存放计算结果到共享对象中
    6. return_dict[taskno] = taskno
    7. if __name__ == '__main__':
    8. manager = Manager()
    9. # 创建 类似字典的 跨进程 共享对象
    10. return_dict = manager.dict()
    11. plist = []
    12. for i in range(10):
    13. p = Process(target=f, args=(i, return_dict))
    14. p.start()
    15. plist.append(p)
    16. for p in plist:
    17. p.join()
    18. print('get result...')
    19. # 从共享对象中取出其他进程的计算结果
    20. for k, v in return_dict.items():
    21. print(k, v)

    JSON

    序列化和反序列化

    Python中内置了json这个库,可以 方便的把内置的数据对象 序列化为json格式文本的字符串。

    1. import json
    2. historyTransactions = [
    3. {
    4. 'time': '20300101070311', # 交易时间
    5. 'amount': '3088', # 交易金额
    6. 'productid': '45454455555', # 货号
    7. 'productname': 'iphone30' # 货名
    8. },
    9. {
    10. 'time': '20300101050311', # 交易时间
    11. 'amount': '18', # 交易金额
    12. 'productid': '453455772955', # 货号
    13. 'productname': '饼干' # 货名
    14. }
    15. ]
    16. if __name__ == '__main__':
    17. # dumps 方法将数据对象序列化为 json格式的字符串
    18. jsonstr = json.dumps(historyTransactions)
    19. print(jsonstr)
    1. import json
    2. historyTransactions = [
    3. {
    4. 'time': '20300101070311', # 交易时间
    5. 'amount': '3088', # 交易金额
    6. 'productid': '45454455555', # 货号
    7. 'productname': 'iphone30' # 货名
    8. },
    9. {
    10. 'time': '20300101050311', # 交易时间
    11. 'amount': '18', # 交易金额
    12. 'productid': '453455772955', # 货号
    13. 'productname': '饼干' # 货名
    14. }
    15. ]
    16. if __name__ == '__main__':
    17. # dumps 方法将数据对象序列化为 json格式的字符串
    18. jsonstr = json.dumps(historyTransactions)
    19. print(jsonstr)
    20. print('================')
    21. print(json.dumps(historyTransactions, ensure_ascii=False, indent=4))
    22. print('================')
    23. jsonstr = '[{"time": "20300101070311", "amount": "3088", "productid": "45454455555", "productname": "iphone7"}, {"time": "20300101070311", "amount": "18", "productid": "453455772955", "productname": "\u5999\u5999\u5999"}]'
    24. translist = json.loads(jsonstr)
    25. print(translist)
    26. print(type(translist))

    装饰器

    Python中装饰器通常用来装饰函数、或者类的方法。

    通常被装饰后的函数, 会在原有的函数基础上,增加一点功能。

    装饰器经常被用在库和框架中, 给别的开发者使用。

    这些库的开发者预料到 使用者 开发的函数可能需要 一些增强的功能。

    但是 这些库的开发者 没法去改使用者的代码, 就可以把这些增强的部分做在 装饰器函数中。

    这样使用者,只需要在他们的函数前面上@xxx 就使用了这些增强的功能了。

    基础示例:

    1. import time
    2. # 定义一个装饰器函数
    3. def sayLocal(func):
    4. def wrapper():
    5. curTime = func()
    6. return f'当地时间: {curTime}'
    7. return wrapper
    8. @sayLocal
    9. def getXXXTime():
    10. print()
    11. return time.strftime('%Y_%m_%d %H:%M:%S', time.localtime())
    12. if __name__ == '__main__':
    13. # 装饰 getXXXTime
    14. # getXXXTime = sayLocal(getXXXTime)
    15. print(getXXXTime())

    进阶示例-被装饰的函数有参数:

    1. import time
    2. def sayLocal(func):
    3. def wrapper(*args, **kargs):
    4. curTime = func(*args, **kargs)
    5. return f'当地时间: {curTime}'
    6. return wrapper
    7. @sayLocal
    8. def getXXXTimeFormat1(name):
    9. curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    10. return f'{curTime} ,数据采集者:{name} '
    11. @sayLocal
    12. def getXXXTimeFormat2(name, place):
    13. curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    14. return f'{curTime} ,数据采集者:{name} , 采集地:{place}'
    15. if __name__ == '__main__':
    16. print(getXXXTimeFormat1('张三'))
    17. print(getXXXTimeFormat2('张三', place='北京'))

    进阶示例-装饰器函数自身有参数:

    1. # 添加输出日志的功能
    2. def logging(flag):
    3. def decorator(fn):
    4. def inner(num1, num2):
    5. if flag == "+":
    6. print("--正在努力加法计算--")
    7. elif flag == "-":
    8. print("--正在努力减法计算--")
    9. result = fn(num1, num2)
    10. return result
    11. return inner
    12. # 返回装饰器
    13. return decorator
    14. # 使用装饰器装饰函数
    15. @logging("+")
    16. def add(a, b):
    17. result = a + b
    18. return result
    19. @logging("-")
    20. def sub(a, b):
    21. result = a - b
    22. return result
    23. if __name__ == '__main__':
    24. result = add(1, 2)
    25. print(result)
    26. result = sub(1, 2)
    27. print(result)

    加密

    算法计算结果长度
    MD516字节
    SHA120字节
    SHA22428字节
    SHA25632字节
    SHA38448字节
    SHA51264字节

    典型应用场景:

    校验拷贝下载文件

    校验信息有效性

    使用 Python 内置库 hashlib 创建hash值。

    示例:

    1. import hashlib
    2. if __name__ == '__main__':
    3. # 使用 md5 算法
    4. # m = hashlib.md5()
    5. # 如果你想使用别的哈希算法,比如, sha256 算法,只需要修改为对应的函数 sha256()即可
    6. m = hashlib.sha256()
    7. # 要计算的源数据必须是字节串格式
    8. # 字符串对象需要encode转化为字节串对象
    9. m.update("ML李嘉图|mllijaitu".encode())
    10. # 产生哈希值对应的bytes对象
    11. resultBytes = m.digest()
    12. # 产生哈希值的十六进制表示
    13. resultHex = m.hexdigest()
    14. print(resultHex)

    SSH远程操作

    Python第三方库 Paramiko 就是作为ssh客户端远程控制Linux主机 的。

    1. exec_command 是每次执行都是 新打开一个channel的东西执行,
    2. 每个channel都是命令执行的环境,每执行命令都是一个新的执行环境,不在上次执行的环境里面,
    3. 相当于 每次都在各自的执行环境里面,和前面的执行环境没有关系。
    4. 多个命令一起执行,用分号隔开,像这样:
    5. stdin, stdout, stderr = ssh.exec_command("cd testdir;pwd")

    操作单台主机:

    1. # 单台主机操作
    2. import paramiko
    3. #############################配置信息#####################################
    4. # 登陆参数设置
    5. hostname = ""
    6. host_port = 22
    7. username = "root"
    8. password = ""
    9. ########################################################################
    10. def ssh_client_con():
    11. """创建ssh连接,并执行shell指令"""
    12. # 1 创建ssh_client实例
    13. ssh_client = paramiko.SSHClient()
    14. # 自动处理第一次连接的yes或者no的问题
    15. ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
    16. # 2 连接服务器
    17. ssh_client.connect(
    18. port=host_port,
    19. hostname=hostname,
    20. username=username,
    21. password=password
    22. )
    23. # 3 执行shell命令
    24. # 构造shell指令
    25. shell_command = "ls"
    26. stdin, stdout, stderr = ssh_client.exec_command(shell_command)
    27. # 输出返回信息
    28. stdout_info = stdout.read().decode('utf8')
    29. print(stdout_info)
    30. # 输出返回的错误信息
    31. stderr_info = stderr.read().decode('utf8')
    32. print(stderr_info)
    33. def sftp_client_con():
    34. # 1 创建transport通道
    35. tran = paramiko.Transport((hostname, host_port))
    36. tran.connect(username=username, password=password)
    37. # 2 创建sftp实例
    38. sftp = paramiko.SFTPClient.from_transport(tran)
    39. # 3 执行上传功能
    40. local_path = "" # 本地路径
    41. remote_path = "" # 远程路径
    42. put_info = sftp.put(local_path, remote_path, confirm=True)
    43. print(put_info)
    44. print(f"上传{local_path}完成")
    45. # 4 执行下载功能
    46. save_path = "" # 本地保存文件路径
    47. sftp.get(remotepath=remote_path, localpath=save_path)
    48. print(f'下载{save_path}完成')
    49. # 5 关闭通道
    50. tran.close()
    51. if __name__ == '__main__':
    52. # 调用函数执行功能
    53. ssh_client_con()
    54. # sftp_client_con()

    Python面向对象编程

    类变量与实例变量

    1. # 创建一个学生类
    2. class Student:
    3. # number属于类变量,不属于某个具体的学生实例
    4. number = 0
    5. # 定义学生属性,初始化方法
    6. # name和score属于实例变量
    7. def __init__(self, name, score):
    8. self.name = name
    9. self.score = score
    10. Student.number = Student.number + 1
    11. # 定义打印学生信息的方法
    12. def show(self):
    13. print("Name: {}. Score: {}".format(self.name, self.score))
    14. # 实例化,创建对象
    15. student1 = Student("John", 100)
    16. student2 = Student("Lucy", 99)
    17. print(Student.number) # 打印2
    18. print(student1.__class__.number) # 打印2

    类方法

    有些变量只属于类,有些方法也只属于类,不属于具体的对象。

    你有没有注意到属于对象的方法里面都有一个self参数, 比如__init__(self)show(self)?

    self是指对象本身。

    属于类的方法不使用self参数, 而使用参数cls,代表类本身。

    另外习惯上对类方法我们会加上@classmethod的修饰符做说明。

    1. class Student:
    2. # number属于类变量,不属于某个具体的学生实例
    3. number = 0
    4. # 定义学生属性,初始化方法
    5. # name和score属于实例变量
    6. def __init__(self, name, score):
    7. self.name = name
    8. self.score = score
    9. Student.number = Student.number + 1
    10. # 定义打印学生信息的方法
    11. def show(self):
    12. print("Name: {}. Score: {}".format(self.name, self.score))
    13. # 定义类方法,打印学生的数量
    14. @classmethod
    15. def total(cls):
    16. print("Total: {0}".format(cls.number))
    17. if __name__ == '__main__':
    18. # 实例化,创建对象
    19. student1 = Student("John", 100)
    20. student2 = Student("Lucy", 99)
    21. Student.total() # 打印 Total: 2

    类的私有属性和私有方法

    类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问。

    1. # 创建一个学生类
    2. class Student:
    3. # 定义学生属性,初始化方法
    4. # name和score属于实例变量, 其中__score属于私有变量
    5. def __init__(self, name, score):
    6. self.name = name
    7. self.__score = score
    8. # 定义打印学生信息的方法
    9. def show(self):
    10. print("Name: {}. Score: {}".format(self.name, self.__score))
    11. # 实例化,创建对象
    12. student1 = Student("John", 100)
    13. student1.show() # 打印 Name: John, Score: 100
    14. student1.__score # 打印出错,该属性不能从外部访问。

    @property

    1. # 创建一个学生类
    2. class Student:
    3. # 定义学生属性,初始化方法
    4. # name和score属于实例变量, 其中score属于私有变量
    5. def __init__(self, name, score):
    6. self.name = name
    7. self.__score = score
    8. # 利用property装饰器把函数伪装成属性
    9. @property
    10. def score(self):
    11. print("Name: {}. Score: {}".format(self.name, self.__score))
    12. if __name__ == '__main__':
    13. # 实例化,创建对象
    14. student1 = Student("John", 100)
    15. student1.score # 打印 Name: John. Score: 100

    类的继承

    1. # 创建父类学校成员SchoolMember
    2. class SchoolMember:
    3. def __init__(self, name, age):
    4. self.name = name
    5. self.age = age
    6. def tell(self):
    7. # 打印个人信息
    8. print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ")
    9. # 创建子类老师 Teacher
    10. class Teacher(SchoolMember):
    11. def __init__(self, name, age, salary):
    12. SchoolMember.__init__(self, name, age) # 利用父类进行初始化
    13. self.salary = salary
    14. # 方法重写
    15. def tell(self):
    16. SchoolMember.tell(self)
    17. print('Salary: {}'.format(self.salary))
    18. # 创建子类学生Student
    19. class Student(SchoolMember):
    20. def __init__(self, name, age, score):
    21. SchoolMember.__init__(self, name, age)
    22. self.score = score
    23. def tell(self):
    24. SchoolMember.tell(self)
    25. print('score: {}'.format(self.score))
    26. if __name__ == '__main__':
    27. teacher1 = Teacher("John", 44, "$60000")
    28. student1 = Student("Mary", 12, 99)
    29. teacher1.tell()
    30. student1.tell()

    静态变量和静态方法

    1. # 创建一个学生类
    2. class Student:
    3. # number属于类变量,定义在方法外,不属于具体实例
    4. number = 0
    5. # 定义学生属性,初始化方法
    6. # name和score属于实例变量,定义在方法里
    7. def __init__(self, name, score):
    8. self.name = name
    9. self.score = score
    10. Student.number = self.number + 1
    11. # 定义打印学生信息的方法
    12. def show(self):
    13. print("Name: {}. Score: {}".format(self.name, self.score))
    14. # 静态方法无法使用cls和self参数访问类或实例的变量
    15. @staticmethod
    16. def func1():
    17. print("this is static function!")
  • 相关阅读:
    Uboot spi-nor 设备信息定义及3地址模式和4地址模式的理解
    漫谈AI 时代的信息模型
    Blog搭建:pycharm+虚拟环境+django
    基于SSM开发自行车在线租赁管理系统
    OpenCV透视变换——将斜方向的图片转成正方向鸟瞰图
    【DevOps】Git 图文详解(七):标签管理
    基于Intel Lake-UP3平台的超声设备方案设计,提供出色的图形和AI性能
    Android插件化学习之加载插件资源
    golang gin——controller 模型绑定与参数校验
    UVM 事务级建模TLM 单向/多向通信 端口 FIFO通信
  • 原文地址:https://blog.csdn.net/jh035/article/details/128062088