Python元类
2017-02-08 本文已影响0人
FangHao
类也是对象
在Python中一切都是对象,类也不例外。所以可以对类进行以下操作。
1.可以当做参数传递
2.可以添加属性
3.可以赋给变量
代码如下:
#coding=utf-8
class Person():
pass
# 可以赋值
print(Person())
p = Person()
print(p)
# 可以当做参数传递
def printClass(patern):
print(patern)
printClass(Person())
# 可以添加属性
Person.name = 'Python'
print(Person.name)
运行结果如下:
type
type其实就是元类,type的作用有两个,第一是查看对象的类型(也可以理解为这个对象是由什么创建创建出来的),第二是可以创建类
代码如下:
#coding=utf-8
class Person():
pass
print(type(Person))
print(type(type(Person)))
运行结果如下:
所以我们可以知道所有的类都是由type创建出来的,如果print(type(type)),最终显示的还是type(这里应该是采用了一个递归的方式)
使用type创建类
代码如下:
#coding=utf-8
Test1Class = type('Test1',(),{})
test1 = Test1Class()
print(test1)
Test2Class = type('Test2',(Test1Class,),{'num':100})
test2 = Test2Class()
print(test2)
print(test2.num)
def __init__(self,age):
self.age = age
def instancemethod(self,name):
print('实例方法')
print(name)
print(self.age)
@classmethod
def classmethod(cls):
print('类方法')
cls.numtest3 = 300
@staticmethod
def staticmethod():
print('hello world')
#print(numtest3)
Test3Class = type('Test3',(Test2Class,),{'__init__':__init__,'instance':instancemethod,'class3':classmethod,'static':staticmethod,'numtest3':200})
test3 = Test3Class(18)
print(test3)
print(test3.instance('xiaohua'))
print(test3.numtest3)
print(test3.class3())
print(test3.static())
print(test3.num)
print(test3.numtest3)
运行结果如下:
metaclass
class中的变量__metaclass__
可以来决定类是由谁来创建
代码如下:
#coding=utf-8
class UpperAttrMetaClass(type):
#__new__方法默认需要传cls参数、后面三个参数依次代表:类名,类的集成,类的属性。默认由系统传递
def __new__(cls,future_class_name,future_class_parents,future_class_attr):
# 取出future_class_attr中属性名以__开头的,并保存在attrs这个元组中
attrs = ((name,value) for name,value in future_class_attr.items() if not name.startswith('__'))
# 将attrs元组再解开然后将其中name改为大写,改成字典保存到uppercase_attrs中
uppercase_attrs = dict((name.upper(),value) for name,value in attrs)
# 1.通过type来做类对象的创建
# return type(future_class_name,future_class_parents,uppercase_attrs)
# 2.通过复用type.__new__的方法来创建类对象
# return type.__new__(cls,future_class_name,future_class_parents,future_class_attr)
# 3.通过super方法创建类对象
return super(UpperAttrMetaClass,cls).__new__(cls,future_class_name,future_class_parents,future_class_attr)
# python2用法,python3也能用
class Foo(object):
__metaclass__ = UpperAttrMetaClass
bar = 'bip'
# python3用法
# class Foo(object,metaclass = UpperAttrMetaClass):
# bar = 'bip'
# hasattr用来检测类中是否有某属性
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))
Python做了如下的操作:
- Foo中有metaclass这个属性吗?如果是,Python会通过metaclass创建一个名字为Foo的类(对象)
- 如果Python没有找到metaclass,它会继续在Bar(父类)中寻找metaclass属性,并尝试做和前面同样的操作。
- 如果Python在任何父类中都找不到metaclass,它就会在模块层次中去寻找metaclass,并尝试做同样的操作。
- 如果还是找不到metaclass,Python就会用内置的type来创建这个类对象。