python中的元类

python中的元类大家都可能比较很陌生,因为大家都听说过99%的情况下是用不到元类的,但是大家对类确很了解,大家都知道在python中万物皆对象,那么python中的类是不是对象呢?

对象的样子:

1,对象可以在程序中动态的进行创建,python的语言动态特性。

2,对象可以通过__class__获取该对象所属的类。

3,对象可以动态的添加属性,方法。

4,可以使用type查看对象的类型。

class Person(object):
    pass


class Student(object):
    pass


class Student_son(Student):
    pass


input_text = input('输入person,创建person,输入student,创建student。。。')
if input_text == 'person':
    obj = Person()
elif input_text == 'student':
    obj = Student()
else:
    obj = Student()

看上面的代码,三个类实现了动态创建,所以非常满足第一条对象的样子。再看下面的代码,就可以看到Person类完全符合对象的样子2,3,4。

class Person(object):
    def __init__(self):
        pass


p = Person()


print(Person.__class__)
Person.name = '白银'
Person.sayName = lambda a : print('我的名字是', a)
Person.sayName(Person.name)


print(type(Person))
执行结果:

<class 'type'>
我的名字是 白银
<class 'type'>

也就是说:

1,类可以在程序中动态的创建。

2,类可以通过__class__获取该对象所属的类。

3,类是可以动态的添加属性和方法。

4,类可以使用type查看该对象的类型。

可能我花费了很多时间和精力来证明,类也是对象:

def create_class(class_name):
    if class_name == 'Person':
        class Person(object):
            def __init__(self):
                print('我是Person')
        return Person

    elif class_name == 'Student':
        class Student(object):
            def __init__(self):
                print('我是Student')
        return Student

    elif class_name == 'StudentSon':
        class StudentSon(object):
            def __init__(self):
                print('我是StudentSon')
        return StudentSon

    else:
        print('无法创建', class_name)

class_create = create_class('Student')
print(class_create.__class__)
class_create.gender = '男'
class_create.sayHello = lambda : print('hello world')
print(class_create.gender)
class_create.sayHello()
print(type(class_create))

执行结果:

<class 'type'>
男
hello world
 
<class 'type'>

那么结论就是:

python中的类,本质上也是一个对象,type就是元类,就是创建类的类.

这个类就是我们所说的type,从源开始说的话,我们中国有一句古话叫做:道生一,一生二,二生三,三生万物,而这句古话特别吻合我们所说的元类到类,在到对象和属性方法。也就是说,道就是元类,类对象(metaclass)是二,对象是三,对象的属性和方法是万物。是不是特别吻合,好吧佩服一下咱们老祖宗的智慧把。


type的用法:

1,查看当前对象的类型

2,创建类

    语法:type(类名,继承父类的元组,包含属性的字典)

Person = type('Person', (object,), {})
Student = type('Student', (Person,), {'name': '张飞龙', 'say_hello': lambda self: print('大家好,我是', self.name)})

student = Student()
print(type(student))
print(student.name)
student.say_hello()

以上代码通过type创建一个Person类,然后创建的Student类继承了Person,并且有字典的传入,实例化的对象student继承了name属性和say_hello方法。

<class '__main__.Student'>
张飞龙
大家好,我是 张飞龙

3,type原理:

使用type创建类,实际上是:

Student = type()返回的一个类对象

student = Student()

所以,type实际上就是python中给我们提供的元类。

4.自定义元类:

你可以在写一个类的时候为其添加__metaclass__属性,定义了__metaclass__就是定义了这个类的元类。

语法:

        class Person(__metaclass = somecode):somecode 必须返回一个类

                    pass

作用:

        可以让创建出来的类符合自己想要的标准

执行流程:

首先查找当前类中是否有__metaclass__,如果有,则在内存中创建Person这个类对象。

如果当前类没有,则去父类中查找是否有__metaclass__.如果有,则创建类对象 。

如果当前类的父类中也没有__metaclass__。则去当前模块中找。

如果模块中也没有,则使用type进行创建person类对象

# 要求,创建出的所有类,除了私有属性外,其余属性都要大写
def upper_attr(class_name, class_Parent, class_attrs):
    # 这个字典用来存储属性和值
    attrs = {}

    for name, value in class_attrs.items():
        if not name.startswith('__'):
            attrs[name.upper()] = value

    return type(class_name, class_Parent, attrs)

class Myclass(object, metaclass=upper_attr):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    test1 = 'test'
    a = 'a'
    __b = 'b'
    bb = 'bb'
    green = '绿色'

my_class = Myclass()
print(hasattr(Myclass, 'a'))
print(hasattr(Myclass, 'A'))

在上面的例子中,我们定义了一个upper_attr函数用来返回一个类,而这个类作为我们接下来定义的Myclass类的元类,这个元类的元类就是type,因为它是type()函数里出来的,在upper_attr里我们把他本身的方法修改了大写。最后执行代码:

False
True






























  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值