官方文档 https://docs.python.org/zh-cn/3/index.html
基本数据类型及其基本操作
1 2 3 4 5 6 7 8 9 10
| 1. 按照访问方式分 - 直接访问:数字 布尔 - 按照索引:列表、集合、元组 - 按照关键字:字典 映射类型 2. 按照可变和不可变区分 - 不可变:字符串、数字、布尔、元组,集合 - 可变:列表,字典 3. 可迭代与不可迭代 - 可迭代即可以被 for 遍历: 元组、集合 、列表,字典,字符串、 - 不可迭代:数字、布尔
|
数字 num_
| 基本操作 |
含义 |
int(num_) |
强转整数 |
oct(num_) |
转八进制 |
hex(num_) |
转十六进制 |
bin(num_) |
转二进制 |
float(num_) |
强转浮点数 |
num_.isdigit() |
判断是否为数字类型 |
num_.isdecimal() |
判断是否为浮点类型 |
字符串 str_
| 基本操作 |
含义 |
str_1 + str_2 |
拼接str_1,str_2 |
''.join(str_) |
用c拼接str_ |
str_[start:end:step] |
索引,支持正负索引/切片 |
len(str_) |
计算长度 |
'' in str_ |
成员判断 |
str_.strip('') |
去除两侧指定字符 |
str_.rstrip('') |
去除右侧指定字符 |
str_.lstrip('') |
去除左侧指定字符 |
str_.split('') |
根据指定字符切分 |
str_.upper() |
转大写 |
str_.lower() |
转小写 |
str_ * n |
重复n次 |
str_.islower() |
判断小写 |
str_isupper() |
判断大写 |
str_.startswith('') |
判断开头是否为指定字符 |
str_.endswith('') |
判断结尾是否为指定字符 |
str_.find('',[start,end]) |
查找(从左往右) |
str_.rfind('') |
查找(从右往左) |
str_.index('') |
查找,不存在则报错 |
str_.rindex('') |
查找(从右往左),不存在则报错 |
str_.count('') |
统计指定字符个数 |
str_.center(len(str_) + n,'c') |
用c填充原字符至len(str_)+n长 |
str_.ljust(len(str_) + n,'c') |
只填充右侧 |
str_.rjust(len(str_) + n,'c') |
只填充左侧 |
str_.zfill(len(name)) + n |
填充,不足补0 |
str_.capitalize() |
句首字母大写 |
str_.title() |
每个单词首字母大写 |
str_.swapcase() |
大小写翻转 |
str_.isalnum() |
是否字符串中包含数字和字母 |
str_.isalpha() |
是否仅包含字母 |
str_.isidentifier() |
是否包含合法标识符 |
str_.islower() |
是否纯小写 |
str_.isupper() |
是否纯大写 |
str_.isspace() |
是否纯空格 |
str_.istitle() |
是否首字母大写 |
列表 list_
list(<可迭代类型>)
| 基本操作 |
含义 |
list_[start:end:step] |
切片 |
'' in list_ |
成员判断 |
list_.append('') |
追加元素到最后,无返回值 |
list_.extend(<可迭代对象>) |
可追加多个元素 |
list_.insert(n, '') |
索引n处添加元素 |
del list_[n] |
删除 |
list_.pop(n) |
弹出(可选指定索引n) |
list_.remove('') |
删除指定值 |
list_.reverse() |
翻转 |
sorted(list_, reverse=True) |
翻转,有返回值 |
list_.sort([reverse=True]) |
排序,可选翻转 |
字典 dict_[k:v]
| 基本操作 |
含义 |
dict_[k] |
获取v,不存在则报错 |
dict_.get[k] |
获取v,不报错 |
dict_[k]=v |
增 |
dict_.setdefault(k,v) |
增,有返回值,返回v |
dict_1.update(dict_2) |
更新dict_1 |
dict_.update(k=v) |
更新 |
del dict_p[k] |
删除k<=>v |
dict_.pop(k) |
弹出 |
dict_.clear() |
清空 |
dict_.popitem() |
弹出键值对,默认弹最后的 |
len(dict_) |
计算个数 |
dict_.keys() |
键 |
dict_.values() |
值 |
dict_.items() |
键值对 |
c in dict_.keys/values/items() |
成员运算 |
for k, v in dict_.items() |
遍历 |
元组 tuple_
| 基本操作 |
含义 |
tuple_[n] |
索引 |
tuple_[:] |
切片 |
tuple_[n]=v |
不支持索引改值 |
len(tuple_) |
计算个数 |
c in tuple_ |
成员运算 |
tuple_1 + tuple_2 |
拼接 |
tuple_ * n |
*运算,会得到新元组 |
集合 set_
| 基本操作 |
含义 |
set_.add() |
增 |
set_.update(...) |
更新 |
set_.remove(...) |
删除,不存在则报错 |
set_.discard(...) |
删除,不会报错 |
set_.pop() |
弹出,随机,不能指定元素 |
set_.clear() |
清空 |
set_1.intersection(set_2) |
交集 |
set_1.union(set_2) |
并集 |
set_1.difference(set_2) |
差集 |
len(set_) |
计算长度 |
集合内部不可放可变数据类型,每个元素是单独的,无序,数字类型的 hash 值是死的
深浅拷贝
1 2 3 4
| import copy old_list = [1,2,3] new_list = copy().copy(old_list) new_list = copy().deepcopy(old_list)
|
字符编码
1 2
| data_.decode('utf-8') data_.encode('utf-8')
|
文件操作
| 模式 |
主要用途 |
关键特点 |
r |
只读 |
文件必须存在 |
w |
覆盖写入 |
清空或创建文件 |
a |
追加写入 |
追加到末尾,自动创建文件 |
r+ |
读写混合 |
从当前位置覆盖写入 |
w+ |
创建并读写 |
先清空文件,适合临时文件 |
a+ |
追加并读取 |
追加到末尾,但可读取全量内容 |
1 2 3 4 5 6 7
| fp = open('demo.txt', 'r', encoding='utf-8') data = fp.read() fp.close()
with open('demo.txt', 'r', encoding='utf-8') as fp: data = fp.read()
|
| 模式 |
主要用途 |
fp_.read() |
读所有内容 |
fp_.write() |
写入 |
fp_.readline() |
读单行 |
fp_.readlines() |
读多行,读出的数据存放在列表中 |
fp_.readable() |
是否可读 |
fp_.writelines(list_) |
逐个元素写入 |
fp_.flush() |
刷新到磁盘中 |
fp_.seek(指针移动字节数, 模式控制) |
0以文件开头为参照; 1以当前所在位置为参照; 2以文件末尾为参照 |
fp_.tell() |
指针当前所在位置 |
异常捕获
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| try: ... except [Error_type]: ...
try: ... except (Error_type_1, Error_type_2): ...
try: ... except [f_Error_type]: ... except [s_Error_type]: ...
try: ... except [Error_type] as e: print(e)
|
1 2 3 4 5 6 7 8 9 10 11
| raise Error_type
for i in range(10): if i == 6: raise ValueError("不能为6")
for i in range(10): assert i == 6, "不能为6"
|
函数多参数&类型注解
多参传递
1 2 3 4
| def student_(name, age, *args, gender='male', **kwargs): ...
|
1 2 3 4 5
| def student_(name, age) ... student(*stu_list) student(**stu_dict)
|
类型注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def student_(name: str, age: int, score: float, is_male: bool): ...
from typing import Dict, List, Tuple, Set def student_(user_data: Dict[str, int], id_list: List[int], num_tuple: Tuple[str], num_set: Set[int]): ...
def add_(x: int, y: int) -> int: ...
from typing import Union def add_(x: int, y: int) -> Union[str, int]: ...
from typing import Optional def add_(x: int, y: int) -> Optional[,int, None]: ...
|
装饰器&语法糖
在不改变原函数代码和调用方式的基础上额外增加的新功能。基本原理:闭包函数 + 函数对象的组合使用。
无参装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13
| def outer(func): ''' :param func: 每一次需要调用传递的函数 :return: 返回值是内嵌函数 inner 的函数内存地址 ''' def inner(): func() return inner
|
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| def outer(func): def inner(): username = input("username :>>>> ") password = input("password :>>>> ") if username == user_data_dict.get('username') and password == user_data_dict.get('password'): print(f"登录成功") func() else: print("登录失败") return inner def transform(): print(f"这是在转账功能") transform = outer(transform) transform()
def withdral(): print(f"这是取款功能") withdral = outer(withdral)
|
有参装饰器
1 2 3 4 5
| def outer_yes(func): def inner(*args, **kwargs): func(*args, **kwargs) return inner
|
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| def outer(func): def inner(*args, **kwargs): func(*args, **kwargs) return inner def transform(username, money): print(f"向 {username} 转账 {money}") username = 'opp' money= 10000 transform = outer(transform) transform(username, money)
|
语法糖
示例:在不改变原 transform 函数的基础上,添加 timer 功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import time
def timer(func): def inner(): start = time.time() func() end = time.time() print(f"总耗时 :>>>> {end - start} s") return inner def transform(): time.sleep(1) transform = timer(transform) transform()
def timer(func): def inner(): start = time.time() func() end = time.time() print(f"总耗时 :>>>> {end - start} s") return inner @timer def transform(): time.sleep(1)
transform()
|
多层代参语法糖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| def check_user_pwd(tag): if tag == 'username': def check_username(func): def inner(*args, **kwargs): username = input("username :>>>> ").strip() username_dict = user_data_dict.get('username') if not username_dict == username: print(f"当前 {username} 不存在不允许使用") else: func(*args, **kwargs) return inner return check_username elif tag == 'password': def check_password(func): def inner(*args, **kwargs): password = input("password :>>>> ").strip() user_password = user_data_dict.get("password") if user_password != password: print(f"密码错误") else: func(*args, **kwargs)
return inner return check_password
@check_user_pwd(tag="username") @check_user_pwd(tag="password") def transform(username, money): print(f"{username} 转账 {money}")
transform(username='dream', money=6666)
|
迭代器&生成器
迭代器
1 2 3 4 5 6 7
| str_ = "abc"
str_.__iter__() str_.__next__() str_.__next__() str_.__next__()
|
生成器
在需要的时候给你数据,不需要的时候不给数据
yield 关键字
https://blog.csdn.net/mieleizhi0522/article/details/82142856
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def foo(): print("starting...") while True: res = yield 4 print("res:",res) g = foo() print(next(g)) print("*"*20) print(next(g)) print(g.send(7))
|
简单理解就是一个 return ,return 出 4 后并没有赋值给 res ,send 后才真正赋值给 res 。
作为一种节省内存的生成器来使用,eg:
1 2 3 4 5 6 7 8
| def foo(num): print("starting...") while num<10: num=num+1 yield num for n in foo(0): print(n)
|
模块和包
模块
一个 py 文件即一个模块,一般里面有多个 def
包
文件夹有 __init__.py 文件
示例:
calculator 包
file:add.py1 2 3 4 5
| def add(x, y): print("加法功能") if not x.isdigit() or not y.isdigit(): return False, f'当前数字格式错误' return True, int(x) + int(y)
|
file:__init__.py
包外部调用
file:main.py1 2 3 4
| from calculator import add add(x, y)
add.add(x, y)
|
匿名函数
1 2 3 4
|
temp = filter(lambda x: x % 2 == 0, range(1, 10)) print(list(temp))
|
内置函数
强转
| 函数名 |
含义 |
str() |
… |
int() |
… |
floadt() |
… |
list() |
… |
tuple() |
… |
bool() |
… |
set() |
… |
dict() |
… |
进制转换
| 函数名 |
含义 |
bin() |
10->2 |
oct() |
10->8 |
hex() |
10->16 |
数学运算
| 函数名 |
含义 |
abs() |
绝对值 |
divmod(被除数,除数) |
商和余数 |
round( ,小数点位数) |
四舍五入 |
pow(base, exponent[, mod]) |
幂次方, mod模数 |
sum() |
… |
min() |
… |
max() |
… |
complex() |
复数转换 |
数据结构相关
| 函数名 |
含义 |
reversed() |
翻转 |
slice() |
切片 |
len() |
计算长度 |
sorted() |
排序 |
enumerate() |
枚举 |
字符串相关
| 函数名 |
含义 |
format(str_, '^n') |
n位中居中对齐 |
format(str_, '<n') |
左对齐 |
format(str_, '>n') |
右对齐 |
format(num, 'b') |
进制转换,二进制 |
format(num, 'd') |
十进制 |
format(num, 'o') |
八进制 |
format(num, 'x') |
十六进制(小写) |
format(num, 'X') |
十六进制(大写) |
format(num, 'c') |
转unicode |
format(num, '0.2e') |
科学计数小写,保留后两位 |
format(num, '0.2E') |
科学计数大写,保留后两位 |
format(num, '0.2f') |
小数点计数,保留后两位 |
format(num, 'F') |
小数点计数,很大的时候输出INF:… |
bytes(str_, 'utf-8') |
指定编码方式 |
bytearray(str_, 'utf-8') |
获取字节数组 |
repr(str_) |
得到字符串的原始样式 |
字符编码相关
| 函数名 |
含义 |
ord(c_) |
得到ASCII值 |
chr(num_) |
相反 |
ascii() |
类似repr,不过会自动转义\x等字符 |
输入输出
hash算法
| 函数名 |
含义 |
hash() |
计算不可变数据类型的哈希值 |
文件操作
其他
| 函数名 |
含义 |
help() |
… |
callable() |
判断是否可被用()调用 |
dir() |
列出当前作用域中的所有变量和函数名 |
id() |
获取当前变量的内存地址 |
breakpoint() |
调试器 |
compile() |
编译字符串为可执行的代码 |
getattr() |
从对象中获取变量名对应的属性值 |
isinstance() |
判断当前变量是否是指定类型 |
issubclass() |
判断当前类是否是另一个累的子类 |
globals() |
查看全局名称空间 |
locals() |
查看局部名称空间 |
map(def_, list_) |
将可迭代类型中的每一个元素作为参数传递给前面的函数 |
iter() |
生成迭代器对象 |
next() |
生成器或迭代器向下取值 |
memoryview() |
查看内存 |
delattr() |
从对象中删除属性 |
classmethod() |
类的静态方法 |
hasatter() |
从对象中判断是否具有该属性 |
zip() |
将两个或三个及以上的数据进行打包 |
anext() |
获取异步迭代器的下一个元素 |
aiter() |
获取异步迭代器对象 |
any() |
判断是否有任意一个元素为 True |
all() |
判断是否所有元素都为 True |
filter() |
过滤 |
exec() |
执行字符串形式的代码,指令 |
eval() |
执行字符串形式的代码 |
frozenset() |
冻结集合,不能往里面加东西 |
面向对象
封装&继承&多态&
封装
私有方法&私有属性,方法和属性前加__
property 一个特殊的属性,将函数的返回值作为数据属性返回
1 2 3 4 5 6 7 8 9 10 11
| class Student: def __init__(self, name): self.name = name @property def vip_name(self): return self.name
student = Student(name='dream') print(student.vip_name)
|
应用示例:(主要目的还是对私有属性的操作)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| class Person(object): def __init__(self, name): self.__name = name @property def vip_name(self): return self.__name @vip_name.setter def vip_name(self, value): print(value) self.__name = value @vip_name.deleter def vip_name(self): del self.__name
person = Person(name='dream')
print(person.vip_name)
person.vip_name = 'opp' print(person.vip_name)
del person.vip_name print(person.vip_name)
|
继承
1 2 3 4 5 6 7 8 9 10
| class son(father): ...
class son(father): def __init__(self, name, sex, age, title): super().__init__(name, sex, age) self.title = title
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| class A: def hello(self): print("Hello from A") class B(A): def hello(self): print("Hello from B") class C(B): def hello(self): print("Hello from C") print(C.mro())
|
抽象类
类创建添加 metaclass=abc.ABCMeta ,对应方法添加装饰器 @abc.abstractmethod
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import abc import json
class Animal(metaclass=abc.ABCMeta): def __init__(self, color, foot, hand): self.color = color self.foot = foot self.hand = hand def speak(self): print(f'任何动物都能叫') @abc.abstractmethod def walk(self): ... class BlackBear(Animal): def __init__(self, color, foot, hand): super().__init__(color, foot, hand) def walk(self): ... bear = BlackBear('black', 2, 2) print(bear.color) bear.speak()
|
多态
父类被多个子类继承,并重写父类对应的方法
绑定方法&非绑定方法
绑定方法
即正常方法,特征是会自动补全 self (类的实例对象本身),类调用时需主动传入对象Student.talk(s)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Student(object): def __init__(self, name): self.name = name def talk(self): print(f'{self.name} is talking')
s = Student('dream') s.talk()
Student.talk(s)
|
对应的方法添加 @classmethod 装饰器,特征是自动补全 cls (类本身),类可直接调用该方法。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Student(object): def __init__(self, name): self.name = name @classmethod def read(cls, *args, **kwargs): ''' :return: 调用当前方法的类 ''' obj = cls(*args, **kwargs) print(f'{obj.name} is reading') stu = Student('dream')
stu.read('dream')
Student.read('dream')
|
非绑定方法
对应的方法添加 @staticmethod 装饰器,特征是不会自动补全任何参数,类和对象可直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Student(object): def __init__(self, name): self.name = name @staticmethod def write(): print("is writing") stu = Student('dream')
stu.write()
Student.write()
|
面向对象的其他相关操作
| 函数 |
含义 |
getattr(obj, key) |
获取属性 |
hasattr(obj, key) |
判断当前属性是否存在 |
setattr(obj, key, value) |
向当前对象中设置属性值和属性名 |
delattr(obj, key) |
删除对象中指定的属性 |
不光是属性,类中的方法也可以进行这些操作,getattr 获取到该函数后还可以调用。
部分魔术方法
部分引用: https://blog.csdn.net/qq_37085158/article/details/124986720
__init__
实例化类得到对象时自动触发
__getitem__
允许其实例使用[]运算符来获取属性
1 2 3 4 5 6 7 8 9 10 11 12 13
| class GetTest(object): def __init__(self): self.info = { 'name': 'Bob', 'country': 'UUU', } def __getitem__(self, i): return self.info[i] foo = GetTest() print(foo['name'])
|
__del__
对象关闭销毁时自动触发
__call__
让类的实例具有类似于函数的行为,把对象当做函数调用的时候自动触发
1 2 3 4 5 6 7
| class A(object): def __call__(self, *args, **kwargs): pass
a = A() a()
|
__slots__
限制当前类只能有指定的属性
1 2 3 4 5 6 7 8 9 10 11
| class WithSlots: __slots__ = ['name', 'age'] def __init__(self, name, age): self.name = name self.age = age
with_slots = WithSlots("Bob", 25) with_slots.new_attr = "I am a new attribute"
|
__str__
打印当前对象的时候可指定改变对象的字符串现实,打印当前对象时会触发,打印该方法的返回值
1 2 3 4 5 6 7 8 9 10 11 12
| class Cat: def __init__(self, name, sex): self.name = name self.sex = sex
def __str__(self): return f"我是一只可爱的小{self.sex}猫咪,我的名字是{self.name}"
>>> cat = Cat("小白", "公") >>> print(cat)
|
__repr__
改变对象的字符串现实,表述某个对象在内存中的展示形式。如果在终端直接输入一个对象,然后按回车,那么将会执行这个对象的__repr__方法。
- 此方法是
__str__()的“备胎”,如果找不到__str__()就会找__repr__()方法
%r默认调用的是__repr__()方法,%s调用__str__()方法
repr()方法默认调用__repr__()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class A(object): def __init__(self, name, age): self.name = name self.age = age def __str__(self): msg = 'name:{},age:{}'.format(self.name, self.age) return msg def __repr__(self): msg = 'name--->{},age--->{}'.format(self.name, self.age) return msg a = A('za', 34) print('%s' % a)
print('%r' % a)
print(a) print(repr(a))
|
__new__
对象实例化时被调用,先触发__new__才会触发__init__。
- 接受的第一个参数是 cls ,代表实例化的类。
- 至少需要返回一个该类的新实例(通常是调用超类的
__new__ 方法来完成。
- 该方法执行后,新创建的对象会作为第一个参数传递给
__init__方法来进行初始化
1 2 3 4 5 6 7 8 9 10
| class Person(object): def __init__(self): print('__init__(): 我也被调用啦~')
def __new__(cls, *args, **kwargs): print('__new__(): 哈哈我被调用啦~')
per = Person() print(per)
|
None说明没有创建对象,因为我们重写了__new__方法,__new__方法不再具有创建对象的功能,只有打印的功能。
调用父类的__new__方法,创建当前对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Person(object): def __init__(self): print('__init__(): 我也被调用啦~')
def __new__(cls, *args, **kwargs): print('__new__(): 哈哈我被调用啦~') ret = super().__new__(cls) return ret
per = Person()
print(per)
|
__dict__
获取类或对象的内部成员结构,主要用来获取用户自定义的属性,以及这些属性对应的值,返回的是一个字典。
__doc__
获取类或对象内部文档
__name__
获取类名或函数名
__class__
获取当前对象获取的类
__bases__
获取一个类直接继承的所有父类,返回元组
__getattr__
获取当前对象不存在的属性时触发。
仅当属性在实例的 __dict__、类的 __dict__ 或其父类中都找不到时才会调用。
1 2 3 4 5 6 7 8 9 10 11
| class Student(object): def __init__(self, name): self.name = name def __getattr__(self, item): return item s = Student("hello") print(s.name) print(s.age)
|
__getattribute__
每次访问任何实例属性(无论是否存在),会自动调用。
__setattr__
设置对象的属性值的时候触发(无论该属性是否已存在)
1 2 3 4 5 6 7 8 9 10 11
| class MyClass: def __setattr__(self, name, value): print(f"Setting attribute '{name}' to '{value}'") object.__setattr__(self, name, value) obj = MyClass() obj.x = 10 print(obj.x)
|
__delattr__
当尝试删除一个实例属性时(使用del语句),会自动调用
1 2 3 4 5 6 7 8 9 10 11 12
| class MyClass: def __init__(self): self.attr_to_delete = "I will be deleted" def __delattr__(self, name): print(f"Deleting attribute '{name}'") object.__delattr__(self, name) obj = MyClass() del obj.attr_to_delete
|
元类
class MyClass: ... 是创建一个类,那么Myclass类是由谁创建的?MyClass是由type创建的,它不仅可以检查对象的类型,它本身也是一个类,并且是创建其他类的“工厂”。
实际创建类的两种方式:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class MyClass: x = 10 def hello(self): print("Hello")
MyClass = type('MyClass', (), {'x': 10, 'hello': lambda self: print("Hello")})
|
元类就是用来创建类的东西
可以理解为:
作用
为了在类被创建时,自动做一些事情。
eg:想要每个类在创建时:
- 自动给所有方法加上日志记录。
- 自动验证某些属性。
- 强制类必须包含某个特定的方法。
- 改变类的结构(比如把所有属性名转为大写)。
这些操作都可以在类被创建的那一刻(而不是实例化时)通过自定义元类来实现。
示例
所有使用这个元类的类,在创建时自动打印一条消息:“类 XXX 被创建了!”
步骤:
- 定义一个元类:它必须继承自
type。
- 重写
__new__ 方法:__new__ 是在类被创建时调用的,我们可以在这里插入自定义逻辑。
- 在类定义中使用
metaclass= 参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class MyMeta(type): def __new__(cls, name, bases, attrs): """ cls: 当前元类 (MyMeta) name: 要创建的类的名字 (比如 'MyClass') bases: 父类的元组 attrs: 类的属性和方法的字典 """ print(f"元类 MyMeta: 正在创建类 '{name}'") attrs['version'] = '1.0' new_class = super().__new__(cls, name, bases, attrs) return new_class
class MyClass(metaclass=MyMeta): def greet(self): print("Hello from MyClass")
print(MyClass.version) obj = MyClass() obj.greet()
|