零基础学习Python(六)

news2024/11/26 0:58:04

1. 元类的应用

使用元类给对象添加一个固有属性author:

对类名进行限定,要求类名必须是大写字母开头:

class MetaC(type):
    def __init__(cls, name, bases, attrs):
        if not name.istitle():
            raise TypeError("类名必须是大写字母开头~")
        return type.__init__(cls, name, bases, attrs)

限制类实例化时只能传递关键字参数:

class MetaC(type):
    def __call__(cls, *args, **kwargs):
        if args:
            raise TypeError("仅支持关键字参数~")
        return type.__init__(cls, name, bases, attrs)

禁止类进行实例化:

class NoInstance(type):
    def __call__(cls, *args, **kwargs):
        raise TypeError("该类不允许被实例化对象!")

不允许该类创建对象,那么可以使用静态方法或者类方法来使用该类:

只允许类实例化一个对象:

class SimpleInstance(type):
    def __init__(cls, *args, **kwargs):
        cls.__instance = None
        return type.__init(cls, *args, **kwargs)

    def __call__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = type.__call__(cls, *args, **kwargs)
        return cls.__instance

可以看到这个唯一的对象保存在类的_SimpleInstance__instance的变量里。

2. 抽象基类

抽象基类不能被实例化,只能被继承,其子类必须实现其定义的抽象方法。

from abc import ABCMeta, abstractmethod
class Fruit(metaclass=ABCMeta):
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def good_for_health(self):
        pass

要想定义一个抽象基类,只需要指定其metaclass为ABCMeta即可,要定义一个抽象方法,使用abstractmethod装饰器即可。

class Banana(Fruit):
    def good_for_health:
        print("~")

3. 模块和包

一个.py文件就是一个模块,导入模块的三种方式(假设模块名为hello):

import hello
# 此时调用模块函数,使用hello.say_hi()、hello.say_hello()
from hello import say_hi, say_hello
# 此时可能会有命名冲突的问题,即两个模块有同名函数/对象,那么后导入的会覆盖先导入的
import hello as h
# 通过as命名别名可以解决命名冲突的问题,此时调用函数使用h.say_hi()、h.say_hello()

模块在导入过程中,会从头到尾执行一遍模块的所有代码,因此如果不使用if __name__ == "__main__":将一些测试语句包裹起来,那么在导入模块的时候会执行一些没必要的代码。 因为当一个.py文件/一个模块被当做脚本(而不是导入)被独立执行的时候,它的__name__属性就会被赋值为“__main__”。如果一个.py文件/一个模块被导入的时候,它的__name__属性就是模块的名称。

python的包是多个模块的集合,是一个文件夹,里面有必须的一个__init__.py文件,标识这个文件夹是一个python包。导入模块的方式变为:import 包名.模块名。

可以对__init__.py文件进行修改,用于对包进行初始化的操作:

print(f"__init__.py 被调用,此时 __name__ 的值是 {__name__}")

此时打印的是包名。导入包的模块,模块中的__name__的值是包名.模块名。

可以在__init__.py文件里定义全局变量,但是包里的模块不能直接访问这个全局变量(可以编写函数访问全局变量,但是运行该模块会报错),要通过包外的其他模块引用该模块,才可以进行访问。

例如在__init__.py文件中添加两个全局变量:

包内的模块尝试访问x:

这是因为包内模块是看不到这个包的。在包外模块访问包的全局变量是ok的

 在__init__.py里还可以导入包里的某个模块,这样其他模块在导入这个包的时候就会自动导入模块:​​​​​​​ ​​​​​​​

​​​​​​​

导入模块时,使用from 模块名 import *会造成命名空间的污染,为此,python提供了__all__属性来解决这一问题,通过__all__属性来指定特定的模块内的变量和函数才能被导入:

__all__ = ["say_hello", "x"]

x = 250
s = "FishC"

def say_hello():
    print("Hello FishC")

def say_hi():
    print("Hi FishC")

此时,s和say_hi不能被访问到

但是如果不是使用from hello import *,而是使用import hello as h,则可以正常访问:

__all__属性也可以应用在包的__init__.py文件中,现在有一个FC包,里面有三个模块:fc1.py,fc2.py,fc3.py,以及一个空的__init__.py文件,在另一个文件中导入该包:

使用dir()函数可以获取当前作用域的变量和方法,结果如下:

可以看到,并未得到fc1,fc2,fc3三个模块,但是如果在__init__.py里使用__all__属性:

 然后在另一个模块中就可以使用fc1和fc2这两个模块了: 

总结:对于模块来说,如果没有使用__all__属性,使用from 模块名 import *的方式导入,将导入模块的所有内容;对于包来说,如果__init__.py没有使用__all__属性,使用from 包名 import *的方式导入,将不会导入包里的任何模块。 

4. 文件操作

打开一个文件:

f = open('FishC.txt', 'w')

此时会创建一个文件FishC.txt,并且可以对这个文件进行写入:

f.write("I love Python")
f.writelines(["I love FishC\n", "I love my wife."])
f.close()

write方法是写入一个字符串,不会换行。writelines写入的是可迭代对象,注意,该方法也不会换行。文件如果操作完毕,需要调用close方法进行关闭。

使用r+的模式打开文件,既可以读,又可以写:

f = open("FishC.txt", "r+")
f.readable() #返回True
f.writable() #返回True

for item in f:
    print(f)
    

此时,如果使用f.read()方法再去读取该文件,会得到空字符串,因为此时f的文件指针已经指到文件末尾了。使用f.tell()可以查看文件指针的位置: 

f.tell()  # 44

f.seek(0) # 将文件指针移到指定位置,此时移到文件开头
f.readline()  # 读取一行
f.read()  # 读取到文件结束的位置(EOF)

使用flush方法可以在不关闭文件的情况下,将内容写到文件(计算机磁盘)中。

使用truncate方法将文件截取到指定位置,即之后的内容(包括指定位置)全部丢弃:

f.truncate(29)

如果打开文件的模式是'w',并且该文件存在,那么文件原来内容会被全部清空。

open函数总是需要调用close函数,但是文件操作过程中发生异常,那么可能会导致文件对象没有close。针对这个问题,可以使用with语句(上下文管理器)来解决:

with open("FishC.txt", "w") as f:
    f.write("I love FishC.")

使用pickle模块的dump方法可以将python对象(包括字符串、列表、字典等)序列化,即转化为二进制格式: 

import pickle

x, y, z = 1, 2, 3
s = "FishC"
l = ["小甲鱼", 520, 3.14]
d = {"one": 1, "two": 2}

with open("data.pkl", "wb") as f:
    pickle.dump(x, f)
    pickle.dump(y, f)
    pickle.dump(z, f)
    pickle.dump(s, f)
    pickle.dump(l, f)
    pickle.dump(d, f)

使用pickle模块的load方法可以将pickle文件反序列化为Python对象,注意读取顺序为序列化时写入的顺序(即先写入的先读出来,后写入的后读出来):

import pickle

with open("data.pkl", "rb") as f:
    x = pickle.load(f)
    y = pickle.load(f)
    z = pickle.load(f)
    s = pickle.load(f)
    l = pickle.load(f)
    d = pickle.load(f)

print(x, y, z, s, l, d, sep="\n")

 

上述对象有点多,使用元组的方式在写入和读取时打包解包可以简化代码:

import pickle

x, y, z = 1, 2, 3
s = "FishC"
l = ["小甲鱼", 520, 3.14]
d = {"one": 1, "two": 2}

with open("data.pkl", "wb") as f:
    pickle.dump((x, y, z, s, l, d), f)


with open("data.pkl", "rb") as f:
    x, y, z, s, l, d = pickle.load(f)

print(x, y, z, s, l, d, sep="\n")

5. 使用pathlib操作文件路径

pathlib是Python3.4之后才有的包,用于替代os.path。从pathlib中导入Path:

from pathlib import Path

使用cwd方法获取当前路径:

Path是一个类,传入字符串就可以获得一个Path对象:

将Path对象用反斜杠和字符串进行拼接,就可获得一个新的Path对象:

判断Path对象是否为一个文件/文件夹:

判断路径/文件是否存在:

 

通过Path对象的name属性可以获取文件/文件夹的名字,即最后一个反斜杠后面的内容:

通过Path对象的stem属性可以获取文件的文件名(不带后缀):

通过Path对象的suffix属性可以获取文件的后缀:

通过Path对象的parent属性可以获取文件/文件夹的上一级目录:

通过Path对象的parent属性可以获取文件/文件夹的各级目录,以元组的形式存储:

通过Path对象的stat()方法可以获取文件/文件夹的信息,比如stat方法返回的对象中有个属性st_size表示大小(单位为字节):

通过Path对象的resolve()方法可以将相对路径转换为绝对路径:

通过Path对象的iterdir()方法获取当前目录下的所有子文件和子文件夹:

通过Path对象的mkdir()方法创建目录:

如果要创建的目录已存在,调用mkdir方法会报错。如果想要忽略报错,关键字参数exist_ok设为True即可:

如果创建的目录的父目录不存在,也会报错:

如果想要将不存在的父目录也创建,parent参数设置为True即可:

 

通过Path对象的open()方法打开文件,其中可以指定操作模式,比如'w',open方法返回一个文件对象,可以对其进行读写操作:

 

通过Path对象的rename()方法进行重命名:

注意此时只传了一个新文件名字符串,没有传入路径,文件将会被移动到当前工作目录(cwd()方法可以查看当前工作目录)。

通过Path对象的rmdir()方法和unlink()方法删除文件夹和文件:

如果目录不为空,调用rmdir()方法会报错 

 

 通过Path对象的glob()方法来查找文件:

 

6. 将程序发布到PyPI上

将程序发布到PyPI上,将可以让世界上所有的程序员通过pip下载你的代码。具体步骤请参考:模块和包(下)_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2061233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

想提升网站排名?试试轮换IP

在竞争激烈的互联网环境中,提高网站排名是每个中小型网站主的共同目标。其中,轮换IP是一种不容忽视的优化工具。虽然听起来可能有些陌生,但轮换IP却能在提升网站排名方面发挥关键作用。本文将深入探讨轮换IP如何帮助中小型网站提升搜索引擎排…

南大-ICS2021 PA1~PA2.2 学习笔记记录

文章目录 代码github网址ICS2021其他博客基础设施: 简易调试器表达式求值词法分析递归求值如何测试自己的代码 监视点的实现扩展表达式求值的功能实现监视点 阅读源码 2译码执行用RTL表示指令行为实现常用的库函数实现常用的库函数 代码github网址 https://github.com/xiao-ta…

一主一从读写分离

目录 介绍 一主一从 原理 准备 配置主从复制 验证主从复制 一主一从读写分离 安装MyCat schema.xml配置 server.xml配置 测试 介绍 读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作,从数据库提供读操作&am…

Springboot中多线程数据库操作下的事务一致性问题的解决方案

文章目录 1 代码实现1.1 正常情况1.2 异常情况总结 1 代码实现 1.1 正常情况 我们采用手动开启事务的方式 public void add(CountDownLatch countDownLatch) {executor.submit(() -> {TransactionStatus transaction dataSourceTransactionManager.getTransaction(transa…

【HTML】HTML学习之引入CSS样式表

1、CSS样式规则 选择器{属性1:属性值1; 属性2:属性值2; 属性3:属性值3;}2、HTML引入CSS样式表 2.1、行内式 行内式也称为内联样式&#xff0c;是通过标签的style属性来设置元素的样式&#xff0c;其基本语法格式如下: <标签名 style"属性1:属性值1; 属性2:属性值2;…

Proxy/Skeleton

设计模式之&#xff08;十二&#xff09;代理模式_skeleton proxy 模式-CSDN博客 在RMI中&#xff0c;客户端可以通过一个桩&#xff08;Stub&#xff09;对象与远程主机上的业务对象进行通信&#xff0c;由于桩对象和远程业务对象接口的一致&#xff0c;因此对于客户端而言&am…

Maven的一些相关知识【重修】《包括私服搭建!》

mvnrepository.com Maven 下载jar包的位置&#xff01; 【该部分有教程】 这是什么nb代码投稿视频-这是什么nb代码视频分享-哔哩哔哩视频

python之matplotlib (6 等高线和热力图)

等高线 import numpy as np import matplotlib.pyplot as pltdef f(x,y):return (1-x/2x**5y**3)*np.exp(-x**2-y**2) n256 xnp.linspace(-3,3,n) yx X,Ynp.meshgrid(x,y) plt.contourf(X,Y,f(X,Y),8,alpha0.75,cmapviridis) plt.colorbar() Cplt.contour(X,Y,f(X,Y),8,colors…

第64期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

免费图形化nginx管理工具nginxWebUI

nginxWebUI是一款图形化管理nginx配置得工具, 可以使用网页来快速配置nginx的各项功能, 包括http协议转发, tcp协议转发, 反向代理, 负载均衡, 静态html服务器, ssl证书自动申请、续签、配置等, 配置好后可一建生成nginx.conf文件, 同时可控制nginx使用此文件进行启动与重载, 完…

Linux基础软件-软件安装

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux进阶部分又分了很多小的部分,我们刚讲完了Linux日常运维。讲的那些东西都算是系统自带的&#xff0c;但是Linux作为一个…

mklink 命令详解

mklink 命令详解 在命令提示符中输入 mklink 可以查看相关的运行命令。 创建符号链接。MKLINK [[/D] | [/H] | [/J]] Link Target/D 创建目录符号链接。默认为文件符号链接。/H 创建硬链接而非符号链接。/J 创建目录联接。Link 指定新的符号链接名称。Targ…

前端3d动画-----平移 transform: translate3d()

必须加这个属性&#xff1a;transform-style: preserve-3d; perspective: 900px; 设置了景深才能感到近大远小的感觉 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible&q…

CTF中的换表类Crypto题目

目录 [安洵杯 2019]JustBase[SWPUCTF 2021 新生赛]traditional字符替换解密 [BJDCTF 2020]base??字符替换 --》 base64解密 [安洵杯 2019]JustBase VGhlIGdlbxvZ#kgbYgdGhlIEVhcnRoJ#Mgc#VyZmFjZSBpcyBkb!pbmF)ZWQgYnkgdGhlIHBhcnRpY#VsYXIgcHJvcGVydGllcyBvZiB#YXRlci$gUHJ…

图神经网络教程3——循环图神经网络-2

目录 计算下游输出 序列图数据的扩展 图长短期记忆网络 循环转换在RGNN应用于图分类时的作用 数据集 算法 结果和讨论 门控循环单元 优缺点 前文索引 本篇是GRNN的第二篇文章&#xff0c;点击此处可到达第一篇文章的位置。 计算下游输出 一旦我们以图中的每个顶点为…

webm格式怎么转换成mp4?7个有效方法将webm转mp4

在数字媒体的浩瀚宇宙中&#xff0c;视频格式的多样性犹如繁星点点&#xff0c;既点亮了创意的火花&#xff0c;也铺设了内容分享的广阔道路。每一种视频格式都承载着其独特的技术优势与设计初衷&#xff0c;WebM便是其中一颗璀璨的新星&#xff0c;专为优化网络传输而生。它凭…

Unity | Shader基础知识(第二十二集:两次渲染)

目录 一、前言 二、“渲染两次” 三、本次成品介绍 四、第一次渲染代码 五、第二次渲染代码 六、截止目前的所有代码 七、调整代码 八、总结 一、前言 之前一直讲的shader文件中&#xff0c;都只写了一次CG代码。 为了大家对这部分的整体理解&#xff0c;我们这次渲…

微服务的保护

一、雪崩问题及解决方案 1.雪崩问题 微服务之间&#xff0c;一个微服务依赖多个其他的微服务。当一个微服务A依赖的一个微服务B出错时&#xff0c;微服务A会被阻塞&#xff0c;但其他不依赖于B的微服务不会受影响。 当有多个微服务依赖于B时&#xff0c;服务器支持的线程和并…

使用策略模式代替多个ifelse

传统的多个 public class OrderServiceImpl implements IOrderService {Overridepublic String handle(OrderDTO dto) {String type dto.getType();if ("1".equals(type)) {return "处理普通订单";} else if ("2".equals(type)) {return "…

PMP–知识卡片--产品管理知识体系

产品管理是公司为管理一个产品或者产品线的产品计划、产品市场和产品生命周期所采用的组织架构。产品管理是一个典型的强矩阵的管理方式。产品管理是企业或组织在产品生命周期中对产品规划、开发、生产、营销、销售和支持等环节进行管理的业务活动。 项目经理和产品有着直接、间…