万物皆对象,在Python也是这样,类也是对象,但是Python不像Java这样有反射,Python有元类,元类就是创建类的类。
既然类也是对象,所以你可以对类进行如下操作。
1.你可以将它赋值给一个变量
2.你可以拷贝它
3.你可以为它增加属性
4.你可以将它作为函数参数进行传递
5.可以像创建对象一样,动态的创建类
1.type的使用。说明:当只有一个参数的时候,代表判断参数的类型,type(type)依然是type,即元类是类的类,type是类最根本的元类
In [1]: a=1 In [2]: type(a) Out[2]: int In [3]: type(int) Out[3]: type In [4]: a=[] In [5]: type(a) Out[5]: list In [6]: type(list) Out[6]: type In [7]: def func(): ...: pass ...: In [8]: type(func) Out[8]: function In [9]: type(type(func)) Out[9]: type In [10]: type(type) Out[10]: type
2.type(三个参数)。说明,当type()有三个参数时,表示手动的创建类,
type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性(方法)的字典(名称和值))
# 添加类属性 a = 100 # 添加对象属性 def __init__(self): self.obj_a = 100 # 添加对象方法 def obj_fun(self): print("obj_fun") # 添加类方法 @classmethod def cls_fun(cls): print("cls_fun", cls.a) # 添加静态方法 @staticmethod def sta_fun(): print("static_fun") Foo1 = type("Foo", (object,), {"a": a, "obj_fun": obj_fun, "cls_fun": cls_fun, "sta_fun": sta_fun, "__init__": __init__}) print(Foo1.__name__) print(Foo1.a) Foo1.cls_fun() Foo1.sta_fun() f = Foo1() f.obj_fun() print(f.obj_a)
# Foo
# 100
# cls_fun 100
# static_fun
# obj_fun
# 100
3.使用函数的方式创建元类。说明:可以控制创建类的过程,但是最终还是需要依赖于type。
def upper_meta_class(class_name, class_bases, class_attrs): new_class_attrs = {} for key, value in class_attrs.items(): new_class_attrs[key.upper()] = value return type(class_name, class_bases, new_class_attrs) class Foo(object, metaclass=upper_meta_class): a = 100 b = 100 # FOO = upper_meta_class("Foo", (object,), {"a": 1, "b": 2}) # 这种方式可以重新定义返回的类名,所以参数和最终的类名没有关系 # print(FOO.A) # 100 print(Foo.A) # 通过metaclass处理的类,无法更改类名
4.使用类的方式创建元类。说明:你可以在定义一个类的时候为其添加__metaclass__属性。如果找到了,Python就会用它来创建类Foo,如果没有找到,就会用 内建的type来创建这个类。
Python做了如下的操作:
- Foo中有__metaclass__这个属性吗?如果是,Python会通过__metaclass__创建一个名字为Foo的类(对象)
- 如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。
- 如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。
- 如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。
class UpperMetaClass(type): def __new__(cls, class_name, class_bases, class_attrs): new_class_attrs = {} for key, value in class_attrs.items(): new_class_attrs[key.upper()] = value # return type(class_name, class_bases, new_class_attrs) # 第一种 # return type.__new__(cls, class_name, class_bases, new_class_attrs) # 第二种 # return super().__new__(cls, class_name, class_bases, new_class_attrs) # 第三种 ,super()不带参数只支持python3 return super(UpperMetaClass, cls).__new__(cls, class_name, class_bases, new_class_attrs) # 第四种,带参数支持py2和py3 # 使用python3创建元类的方法 class Foo(object, metaclass=UpperMetaClass): a = 100 b = 100 # # 使用python2创建元类的方法 # class Foo(object): # __metaclass__ = UpperMetaClass # a = 100 # b = 100 print(Foo.A) #
总结:
元类就是用来创建这些类(对象)的,元类就是类的类,Python中所有的东西,注意,我是指所有的东西——都是对象。
这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type。
自定义类的创建过程:拦截类的创建,修改类,返回修改之后的类。
Python中元类很少用,引用一句经典的话:
“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到
元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。” —— Python界的领袖 Tim Peters
本文深入探讨了Python中的元类概念,介绍了如何使用type函数创建类,以及如何通过自定义元类来控制类的创建过程。文章还展示了元类的具体应用案例。
1335

被折叠的 条评论
为什么被折叠?



