简要
- python中所有创建的类都是由元类(type)创建而来。
- class 创建一个类,和用type()创建没有区别。
- type(参数1(str), 参数2(tuple), 参数3(dict)),参数名意义:类名,父类,属性及方法名的引用。
- type()一般看来是判断数据类型的作用,在python中,传入参数数量不同所做的事情不同(目的不同),本身是一件很傻的行为。但是python的开发者们肯定是有自己的考虑,所以就只能这样了。
- 创建类的时候有 metaclass这样一个参数(在python2中它是一个魔法属性),这个参数可以是一个函数也可以是一个类,参数对应的函数或者类可以理解为“元类”(我们自己可以指定),默认是type。
- 理解元类及为什么要自定义元类,可以参考装饰器(装饰器文章链接)
- 可以用一个函数充当“元类”(参考代码片1)
- 也可以用类来充当元类。(参考代码片2)
代码1:函数当元类
# -*- coding:utf-8 -*-
def upper_attr(class_name, class_parents, class_attr):
'''把类中的属性名都变成大写'''
# 遍历属性字典,把不是__开头的属性名字变为大写
new_attr = {}
for name, value in class_attr.items():
if not name.startswith("__"):
new_attr[name.upper()] = value # upper(): 小写字母变为大写
# 调用type来创建一个类
return type(class_name, class_parents, new_attr) # 参数名意义(类名,父类,属性及方法名的引用)
class Foo(object, metaclass=upper_attr): # metaclass :创建类的函数。默认是type()
bar = 'bip'
print(hasattr(Foo, 'bar'))
print(hasattr(Foo, 'BAR'))
f = Foo()
print(f.BAR)
# print(f.bar)
# 元类起到的作用是 在创建基本类之前,多添加点自己想要的“东西”(对比于装饰器而言,这是给类加功能,装饰器是给执行函数之前加功能)
代码2:类来当元类
# coding=utf-8
class UpperAttrMetaClass(type): # 继承type类
# __new__ 是在__init__之前被调用的特殊方法
# __new__是用来创建对象并返回之的方法
# 而__init__只是用来将传入的参数初始化给对象
# 你很少用到__new__,除非你希望能够控制对象的创建(比如单例)
# 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__
# 如果你希望的话,你也可以在__init__中做些事情
# 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用
def __new__(cls, class_name, class_parents, class_attr):
# 遍历属性字典,把不是__开头的属性名字变为大写
new_attr = {}
for name, value in class_attr.items():
if not name.startswith("__"):
new_attr[name.upper()] = value
# 方法1:通过'type'来做类对象的创建
return type(class_name, class_parents, new_attr)
# 方法2:复用type.__new__方法
# 这就是基本的OOP编程,没什么魔法。
# return type.__new__(cls, class_name, class_parents, new_attr)
# python3的用法
class Foo(object, metaclass=UpperAttrMetaClass): # 分配空间的时候就会调用__new__方法,达到“元类”的功能
bar = 'bip'
# python2的用法
# class Foo(object):
# __metaclass__ = UpperAttrMetaClass
# bar = 'bip'
print(hasattr(Foo, 'bar')) # hasattr() 函数用于判断对象是否包含对应的属性。
# 输出: False
print(hasattr(Foo, 'BAR'))
# 输出:True
f = Foo()
print(f.BAR)
# 输出:'bip'
补充
不要过分纠结元类,当你纠结的时候,说明你根本就用不到它(这不是我说的,是那个谁谁谁说的-。-)