python 中的元类详解
时间:2022-07-22
本文章向大家介绍python 中的元类详解,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在其他语言中我们都知道类和int,string等类型一样是用来生成对象的。 类就是生成对象的代码段。 在python中任然是这样,但是Python中的类还远不止如此,在python中类也是对象。只是这个对象拥有创建对象的能力。
但是,它的本质仍然是一个对象,于是乎你可以对它做如下的操作:
- 你可以将它赋值给一个变量
- 你可以拷贝它
- 你可以为它增加属性
- 你可以将它作为函数参数进行传递
同时因为类就是对象,所以可以在运行时动态的创建。
def choose_class(name):
… if name == 'foo':
… class Foo(object):
… pass
… return Foo # 返回的是类,不是类的实例
… else:
… class Bar(object):
… pass
… return Bar
…
>>> MyClass = choose_class('foo')
>>> print MyClass # 函数返回的是类,不是类的实例
<class '__main__'.Foo>
>>> print MyClass() # 你可以通过这个类创建类实例,也就是对象
<__main__.Foo object at 0x89c6d4c>
由于类也是对象,所以它们必须是通过什么东西来生成的才对。当你使用class关键字时,Python解释器自动创建这个对象。
使用type来创建类
我们都知道python中的自身,使用type可以知道当前变量的类型
print type(1)
<type 'int'>
print type("1")
<type 'str'>
type可以这样使用
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
比如用type来创建下面的一个类
class Foo(object):
bar = True
使用type简化创建
Foo = type('Foo', (), {'bar':True})
使用继承, 在创建一个下面的子类
class FooChild(Foo):
… pass
FooChild = type('FooChild', (Foo,),{})
print FooChild
<class '__main__.FooChild'>
print FooChild.bar # bar属性是由Foo继承而来
True
使用type为你的类增加方法
def echo_bar(self):
print self.bar
FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
hasattr(Foo, 'echo_bar')
False
hasattr(FooChild, 'echo_bar')
True
my_foo = FooChild()
my_foo.echo_bar()
True
已定义的元类
==type==就是Python在背后用来创建所有类的元类。除此外还有==str==,==int==等内件元类
创建自己的元类
你可以在写一个类的时候为其添加metaclass属性。
class Foo(object):
__metaclass__ = something…
Foo中有metaclass这个属性吗?如果是,Python会在内存中通过metaclass创建一个名字为Foo的类对象。如果Python没有找到metaclass,它会继续在Bar(父类)中寻找metaclass属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到metaclass,它就会在模块层次中去寻找metaclass,并尝试做同样的操作。如果还是找不到metaclass,Python就会用内置的type来创建这个类对象。
比如将属性全部转化为大写
# 元类会自动将你通常传给‘type’的参数作为自己的参数传入
def upper_attr(future_class_name, future_class_parents, future_class_attr):
'''返回一个类对象,将属性都转为大写形式'''
# 选择所有不以'__'开头的属性
attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
# 将它们转为大写形式
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
# 通过'type'来做类对象的创建
return type(future_class_name, future_class_parents, uppercase_attr)
__metaclass__ = upper_attr # 这会作用到这个模块中的所有类
class Foo(object):
# 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中
bar = 'bip'
Python中的一切都是对象,它们要么是类的实例,要么是元类的实例,除了type。type实际上是它自己的元类。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 详细分析Python垃圾回收机制
- PHP实现用session来实现记录用户登陆信息
- django序列化时使用外键的真实值操作
- 网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
- 如何基于Python爬取隐秘的角落评论
- PHP微信网页授权的配置文件操作分析
- php微信公众号开发之关键词回复
- Python 抓取数据存储到Redis中的操作
- PHP常见字符串操作函数与用法总结
- 利用python对excel中一列的时间数据更改格式操作
- Python 私有属性和私有方法应用场景分析
- django 模型字段设置默认值代码
- Python局部变量与全局变量区别原理解析
- 为什么是 Python -m
- Python csv文件记录流程代码解析