8.python之面相对象part.9(初识元类part.1)

初步认识元类

#本篇文章介绍的元类,以及type以python3以上版本为准。

一.关于元类的前言。

在python中,一切皆对象,当然,类也是一个对象。

class c1:

pass

obj1 = c1()

从上面这段例子可以看到,obj1是c1这个类创建出来的一个对象,obj1是由c1去产生的,如果按照前面的理论来理解,类也是一个对象,那么c1是由谁创建出来的呢?

#type函数可以查看类型,也可以用来查看对象的类,二者是一样的

print(type(obj1)) # 输出:<class ‘__main__.c1‘>     表示,obj1 对象由c1类创建

print(type(c1)) # 输出:<type ‘type‘>

也就是说我们定义的类,全部都是由type产生的。

通过这个知识点,可以引出两种创建类的方式。

方式一:使用class关键字定义一个类。

class Foo:

def func(self):

print(‘from func‘)

方式二:通过type定义一个类。

def func(self):

print(‘from func‘)

x=1

Foo=type(‘Foo‘,(object,),{‘func‘:func,‘x‘:1})

二.什么是元类?

所谓的元类,可以理解为它是类的类,元类是去控制如何创建一个类的,就像类是对象的模版一样,元类则是类的模版。

type和元类由什么关系呢?

当一个类没有声明自己的元类时,这个类默认的元类就是type。

不止如此,用户还可以通过type来定义一个元类。

注意!当自定义元类的时候,自己定义的元类一定要继承type!

关于元类参数的剖析:

python2.7ver:

class mytype(type):

def __init__(self,class_name,bases,dict):

print "mytype __init__ runing!!"

print class_name    #类的名字

print bases    #继承的父类

print dict  #类的名称空间字典(也就是类的__dict__)

print self   #定义的类的本体(也就是类的内存地址)

class test_class(object):  #将mytype作为元类,创建一个类,名为test_class

__metaclass__ = mytype   #python2.7中指定元类的方法。

def running(self):

print "runing....."

接下来执行以下代码。

输出:

mytype __init__ runing!!

test_class

(<type ‘object‘>,)

{‘__module__‘: ‘test1‘, ‘__metaclass__‘: <class ‘test1.mytype‘>, ‘running‘: <function running at 0x10e149c08>}

<class ‘test1.test_class‘>

python3.5ver:

class mytype(type):

def __init__(self,class_name,bases,dict):

print("mytype __init__ runing!!")

print(class_name)    #类的名字

print(bases)    #继承的父类

print(dict)  #类的名称空间字典(也就是类的__dict__)

print(self)   #定义的类的本体(也就是类的内存地址)

class test_class(metaclass = "mytype"):  #将mytype作为元类,创建一个类,名为test_class

def running(self):

print("runing.....")

#从输出的结果可以看出,当我们在创建一个类的时候,就会触发元类的__init__构造方法,就好像是用类创建对象的过程一样。

类是如何实例化出属性的呢?下面就通过元类手动来实现这个功能。

python2.7ver:

class mytype(type):

def __init__(self,class_name,bases,dict):

print "mytype __init__ runing!!"

print class_name

print bases

print dict

print self

def __call__(self, *args, **kwargs):  # 当使用类去实例化一个对象的时候,类后面需要加()这就会触发元类中定义的__call__方法。

print "mytype call runing -----> %s,%s,%s" %(self,args,kwargs)

obje  = self.__new__(self) #生成一个空的对象

self.__init__(obje,*args,**kwargs) #调用元类所创建类的构造方法。

return obje #将空对象返回

class test_class(object):

__metaclass__ = mytype

a = 1

def running(self):

print "runing....."

obj1 = test_class()

print obj1.a

时间: 2024-10-12 15:46:42

8.python之面相对象part.9(初识元类part.1)的相关文章

8.python之面相对象part.1(初识类与对象)

一.类和对象的概念. 什么是类 类就是把一类事物相同的特征和动作整合到一起就是类比如说"人"就是一个类. 什么是对象 对象就是基于类创建出来的一个具体存在的事物这个事物包含了将其创造出来的类的特征和动作. 类与对象有什么关系一切的对象都是由类产生的假如说造一支笔首先要有一个造笔的模版上帝制造人也是一样制造一个人也需要一个造人的模版这个模板就是人的"类"然后根据类的定义来产生一支支笔和一个个的人. 什么是实例化 由类产生对象的过程就是实例化类实例化的结果就是一个对象对

8.python之面相对象part.6(反射&__call__,__setattr__,__delattr__,__getattr__)

一.什么是反射? 反射,又被称为自省,主要是指程序本身可以访问,检测,和修改"自己",状态或行为的一种能力. 二.python是如何体现这种反射机制的? 通过字符串去操作对象相关的属性,python中,一切皆对象,所有的地方都可以用到反射. python内部提供了四个实现反射(自省)的函数,这四个函数可以适用于任何的类和对象(这是因为类本身也是一个对象!) 1.hasattr(object,str) 用来检测一个对象中是否有某个字符串对应的方法或者属性. 例如: l1 = [] pri

8.python之面相对象part.2(特殊属性,类方法,静态方法)

一.关于特殊属性(property). 接着上一篇文章继续说,如果想调用python中一个对象的属性,直接使用类或者对象名称在后面加.点然后写上属性名称就可以跳用这个类或者对象的属性了,比如说像下面这样. class person: def __init__(self,career): self.career = career ayumi = person(career="diva") print ayumi.career #ayumi是实例化出来的一个对象后面加.点,后面接属性名,就

python之面相对象进阶

一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(object): 2 pass 3 4 obj = Foo() 5 6 isinstance(obj, Foo) issubclass(sub, super)检查sub类是否是 super 类的派生类 1 class Foo(object): 2 pass 3 4 class Bar(Foo): 5 pass

8.python之面相对象part.8(__slots__属性)

一.__slots__属性有什么作用?为什么要有__slots__属性. 首先来说一说__slots__是什么,__slots__是一个类变量,它里面的值可以是字符串,可以是列表,可以是元组.(如果__slots__这个属性的值为一个字符串,那么意为着这个类生成的对象,只能有一个属性). 那么为什么要用__slots__属性呢? 关于这个问题还要从每个对象的__dict__属性开始说起. 当使用.点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立

【原创】Python 对象创建过程中元类, __new__, __call__, __init__ 的处理

原始type: type是最原始的元类,其__call__方法是在你使用" t_class = type(classname_string, base_classes_tuple, attributes_dict)" 这种语法来使用时, 在__call__方法内使用又会调用type的__new__和__init__方法来创建classname_string的具体类,并初始化类信息.当type(***)调用完成, classname_string代表的类可以用来创建实例了. 元类调用过程

Python 面向对象高级编程——使用枚举和元类

1.1   使用枚举 基于Enum类实现的枚举 >>> fromenum import Enum >>> Month = Enum('Month', ('Jan','Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) >>> for name, member inMonth.__members__.items(): ...    print(name,

Python全栈之路----面向对象开发----元类介绍

储备知识exec,可以被当作函数来看待. 参数1:字符串形式的命令 参数2:全局作用域(字典形式),如果不指定默认就使用globals() 参数3:局部作用域(字典形式),如果不指定默认就使用locals() g = {'x':1, 'y':2} l = {} exec(''' global x,m x = 10 m = 100 z = 3 ''', g, l) python中一切皆对象,对象可以怎么用? 1.都可以被引用,x = obj 2.都可以当作函数的参数传入 3.都可以当作函数的返回值

8.python之面相对象part.5(子类调用父类的方法,以及super关键字)

python中子类要调用父类的某个方法,在python早期版本中是这样实现的: class A: def __init__(self): print "enter A" print "leave A" class B(A): def __init__(self): print "enter B" A.__init__(self) print "leave B" b = B() >>>enter B enter