首页 > 其他分享 >面向对象之元类

面向对象之元类

时间:2022-11-08 16:24:16浏览次数:37  
标签:__ 元类 面向对象 Student print type class 之元类

元类简介

"""推导步骤1:如何查看数据的数据类型"""
    s1 = 'hello word '
    l1 = [11, 22, 33, 44, 55]
    d1 = {'name': 'jason'}
    t1 = (11, 22, 33, 44)
    print(type(s1))  # <class 'str'>
    print(type(l1))  # <class 'list'>
    print(type(d1))  # <class 'dict'>
    print(type(t1))  # <class 'tuple'>
"""推导步骤2:其实type方法是用来查看产生对象的类名"""
    class Student:
        pass
    obj = Student()
    print(type(obj))  # <class '__main__.Student'>
"""推导步骤3:python中一切皆对象,我们好奇type查看类名显示的是什么"""
    class Student:
        pass
    obj = Student()
    print(type(obj))  # <class '__main__.Student'>
    print(type(Student))  # <class 'type'> 幕后黑手居然是他
    class A: pass
    class B: pass
    print(type(A), type(B))  #<class 'type'> <class 'type'>
"""结论:我们定义的类其实都是由type类产生的>>>:元类(产生类的类)"""

创建类的两种方法

# 方式1:使用关键字class
class Teacher:
    school_name = 'moumou'
    def func1(self): pass
print(Teacher)
print(Teacher.__dict__)
# 方式2:利用元类type,type(类名,类的父类,类的名称空间)
cls = type('Student', (object,), {'name': 'jason'})
print(cls)
print(cls.__dict__)
"""
了解知识:名称空间的产生
1.手动写键值对
	针对绑定方法不好定义
2.内置方法exec
	能够运行字符串类型的代码并产生名称空间
"""

元类定制类的产生行为

"""
推导:
	对象是由类加括号然后调用__init__产生自己独立内部名称空间
那么类也是由元类加括号调用元类中的__init__产生自己名称空间
"""
# 1.自定义类:继承type的类也称之为元类
class MyMetaClass(type):  # 继承元类
    def __init__(cls, what, bases=None, dict=None):
        print(cls)  # <class '__main__.myclass'>,就是元类产生的类
        print(what)  # myclass  元类产生的类名
        print(bases)  # ()  类继承的父类,没有继承则为空的元组
        print(dict)  # 元类其实很有趣,就是有点绕  产生的类内部空间的名字
        if not what.istitle():
            raise TypeError('类的首字母需要大写')
        super().__init__(what, bases, dict)  # 重新调用元类的方法


2.指定类的元类:利用关键字metaclass指定产生类的元类
class myclass(metaclass=MyMetaClass):
    desc = '元类其实很有趣,就是有点绕'

class Student(metaclass=MyMetaClass):
    info = '我是学生,我很听话'


print(Student)
print(Student.__dict__)

元类定制对象的产生行为

"""
推导:
	对象加括号会执行该生该对象类里面的__call__
那么类加括号就会执行产生该类的元类里面的__call__
"""
"""给对象添加独有的数据的时候,必须采用关键字参数传参"""
# 先定义一个元类
class MyMetaClass(type):
    def __call__(self, *args, **kwargs):
        print(2)   # 类产生一个对象首先触发元类的__call__
        print(args)  # ('jason', 18)  # args接收元类产生的类产生对象的时候的位置参数
        print(kwargs)  # {'gender': 'male'}  # kwags接收元类产生的类产生对象的时候的关键字参数
        if args:  # 如果args这个元组存在,证明有位置参数
            raise TypeError('必须要求全部都是关键字传参')
        print(3)  # 触发到这里然后返回给__init__接收
        return super().__call__(*args, **kwargs)  # 调用元类方法返回



class Student(metaclass=MyMetaClass):
    def __init__(self, name, age, gender):
        print(1)  # 接收元类__call__产生的
        self.name = name
        self.age = age
        self.gender = gender
        print(4)  # 最后结束,产生一个含有内部独立空间的对象


obj = Student(name='jason', age=18, gender='male')
print(obj.__dict__)

模仿方法之双下new

class MyMetaClass(type):
    def __call__(cls, *args, **kwargs):
        print(cls)  # <class '__main__.Student'>
        # 产生一个空对象(骨架)
        obj = cls.__new__(cls)  # 类在元类中调用__new__()将自己作为参数传入产生一个新的对象
        # 类调用__init__给对象添加独有的数据(血肉)
        cls.__init__(obj, *args, **kwargs)  # 类点__init__给对象添加独立的数据,
        return obj  # 将对象返回


class Student(metaclass=MyMetaClass):
    def __init__(self, name):
        self.name = name+


obj = Student('jason')
print(obj.name)
"""
__new__可以产生空对象
"""

设计模式简介

1.设计模式
	前人通过大量的验证创建出来解决一些问题的固定高效方法
2.IT行业
	23种
        创建型
        结构型
        行为型
 	ps:课下感兴趣可以简单看看
3.单例模式
	类加括号无论执行多少次永远只会产生一个对象
 	目的:
        当类中有很多非常强大的方法 我们在程序中很多地方都需要使用
        如果不做单例 会产生很多无用的对象浪费存储空间
        我们想着使用单例模式 整个程序就用一个对象

标签:__,元类,面向对象,Student,print,type,class,之元类
From: https://www.cnblogs.com/zhanghong1229/p/16870099.html

相关文章