object类
object
类是python中大多数类的祖先类.
class A:
pass
print(A.__mro__)
print(object.__class__)
type类
type类是一个元类
(元始的意思), 用于创建类的类.
元类
就是创建与管理类的类,type
是默认的元类
print(type.__class__)
# 这就是为什么很多内置的类型__class__都是type
print(int.__class__)
print(bool.__class__)
print(tuple.__class__)
print(list.__class__)
元编程
通过元类可以在程序运行过程中动态创建类,这种编程方式称为元编程
type
不但可以查看对象的类, 也可以创建类(所以称为元类)
# type(name, bases, attr)
# name - 类名
# bases - 元组形式的基类
# attr - 字典形式的类的属性
A = type("A", (), {"name":"luxp"})
# type与class语法其实是一回事情, type可以让我们拥有动态创建类的能力
# 相当于
# class MyClass:
# name = "luxp"
# A是一个变量,指向新建的MyClass
print(A.__name__)
a = A()
print(a)
print(a.name)
自定义元类
在类定义的时候, 可以通过metaclass
关键字指定元类
自定义元类示例1
这里使用一个函数作为元类(
任何可调用对象都可以作为元类)
# 利用type动态创建类, 所有没有__前缀的属性名必须大写
def uppercase_attributes(name, bases, attrs):
uppercase_attrs = {}
for attr_name, attr_value in attrs.items():
if not attr_name.startswith('__'):
uppercase_attrs[attr_name.upper()] = attr_value
return type(name, bases, uppercase_attrs)
# 元类
def MyMetaFunction(name, bases, attrs):
print(name, bases, attrs)
return uppercase_attributes(name, bases, attrs)
class MyClass(metaclass=MyMetaFunction):
name = 'john'
age = 30
在这个示例中, 通过元类可以控制创建的类的属性名保持大写
type子类元类
可以通过继承type类来自定义元类
type子类
# 普通类,没有指定元类,默认为type
class A:
pass
print(A.__class__)
# 新元类
class NewMetaClass(type):
pass
# 普通类,指定了元类
class B(metaclass=NewMetaClass):
pass
print(B.__class__)
类的__class__
属性指向他的元类,或者其最近的父类的元类
重写__new__
方法示例
在这个例子中, 通过对__new__
方法重写在元类中添加了对类属性的控制
# 自定义一个元类继承type
# 创建类时,会执行元类的__new__方法
class Coord3D(type):
def __new__(cls, name, bases, attrs):
# 只接受_x、_y、_z
new_attrs = {"_x": attrs.get('_x', None),
"_y": attrs.get('_y', None),
"_z": attrs.get('_z', None)}
# 调用父类的__new__方法创建类
return super().__new__(cls, name, bases, new_attrs)
# 通过metaclass指定Coor3D是元类
# 在创建EarthCoord3D类时多余的_a\_b\_c会被过滤
class EarthCoord3D(metaclass=Coord3D):
_x = 10
_y = 10
_z = 10
_a = 100
_b = 200
_c = 300
print(EarthCoord3D.__dict__)
print(type(EarthCoord3D)
自定义元类应用示例2
根据环境变量不同, 创建不同的类
# 标准表单类
class NormalForm:
input_field = "input"
# 安全表单类
class SafeForm:
input_field = "safe_input"
# 环境变量
safe_status = "safe"
# 表单创建元类
class MetaForm(type):
def __new__(cls, *args, **kwargs):
name, bases, attrs = args
# 修改了基类
if safe_status == "safe" and NormalForm in bases:
bases = (SafeForm,)
return super().__new__(cls, name, bases, attrs)
# 不同环境变量下
# safe_status = ""
class Form(NormalForm, metaclass=MetaForm):
pass
print(Form.__mro__)
print(Form.input_field)
# 不同环境变量下
# safe_status = "safe"
class Form(NormalForm, metaclass=MetaForm):
pass
print(Form.__mro__)
print(Form.input_field)
__subclasscheck__
方法
issubclass
依赖于元类的__subclasscheck__
方法
# A为元类
class A(type):
def __subclasscheck__(self, subclass):
print(self)
if subclass in self.__subclasses__():
print(f"{subclass} is {self}'s subclass")
return True
class B(metaclass=A):
pass
class C(B):
pass
issubclass(B, C)
issubclass(C, B)
__instancecheck__
方法
isinstance
依赖于类的__instancecheck__
方法
class A(type):
def __instancecheck__(self, instance):
print(self)
print(instance)
classes = instance.__class__.__mro__
if self in classes:
print(f"{instance} is {self}'s instance")
return True
class B(metaclass=A):
pass
class C(B):
pass
c = C()
isinstance(c, C)
isinstance(c, B)
type类与object类关系
type类是用于创建类的类
object类是所有类的基类(所有对象的基类)
object类从类型上来属于type类
type类从对象继承关系上属于object类(type类也是一个对象)
# 从mro顺序上看type是object的子类
print(object.__mro__)
# (object,)
print(type.__mro__)
# (type, object)
# 通过bases属性查看
# 从__bases__属性(直接父类组成的元组)观察
# type是object子类
print(type.__bases__)
print(object.__bases__)
# 查看type是不是object的子类
issubclass(type, object)
# True
# object又是type的实例
isinstance(object, type)
# True
# type也是object的实例
isinstance(type, object)
# True
# 更狠的其实,他们也是各自自己的实例
isinstance(type, type)
isinstance(object, object)
# 那他们会不会是一个对象
print(type is object)
# 看上去type与object纠缠不清,甚至出现了先有鸡还是先有蛋的恍惚
# 其实type与object只是python类的两条线顶端
# type用于创建类,决定类长什么样
# object用于确定继承关系
# 出现这样的结果,是由于一些特殊方法得到的结果,这些方法可以控制结果
# __class__: 设定自己的元类类型(实例是类的情况)
# __bases__: 类型的基类-父类
# __instancecheck__: 检查是否是类的实例
# __subclasscheck__: 检查是否是类的子类
讨论区