Python从门到精通:元类-01-元类
Posted 生而为人我很遗憾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python从门到精通:元类-01-元类相关的知识,希望对你有一定的参考价值。
本章主要说一点高级的编程技巧,python中也算是比较常用的一种技巧--元类。有点类似于拦截器或AOP的功能。
一、控制类的创建
对象的类型叫作类,类的类型叫作元类。实例对象由类创建,而类则是由元类创建。类进行创建时会优先执行以下几个方法,通过复写这几个方法就可以控制类的创建过程,规范化代码,然后在类定义时使用metaclass来定义行为,以下三个方法会按顺序执行;
- __prepare__(定义类)
- __new__(实例创建之前)
- __init__(实例创建时)
- __call__(实例创建时)
1.1、基础
class NoInstances(type):
def __call__(self, *args, **kwargs):
raise TypeError("Cant instantiate directly")
# Example,这里最主要的是metacclass的运用
class Spam(metaclass=NoInstances):
def grok(x):
print(Spam.grok)
Spam.grok(30)
s = Spam() #会报错
1.2、单例
class Singleton(type):
def __init__(self, *args, **kwargs):
self.__instance = None
super().__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super().__call__(*args, **kwargs)
return self.__instance
else:
return self.__instance
# Example
class Spam(metaclass=Singleton):
def __init__(self):
print(Creating Spam)
二、控制类型
from abc import ABCMeta, abstractmethod
class IStream(metaclass=ABCMeta):
def read(self, maxsize=None):
pass
def write(self, data):
pass
class MyMeta(type):
# Optional
def __prepare__(cls, name, bases, *, debug=False, synchronize=False):
# Custom processing
pass
return super().__prepare__(name, bases)
# Required
def __new__(cls, name, bases, ns, *, debug=False, synchronize=False):
# Custom processing
pass
return super().__new__(cls, name, bases, ns)
# Required
def __init__(self, name, bases, ns, *, debug=False, synchronize=False):
# Custom processing
pass
super().__init__(name, bases, ns)
class Spam(metaclass=MyMeta, debug=True, synchronize=True):
pass
class Spam(metaclass=MyMeta):
debug = True
synchronize = True
pass
三、控制属性
from collections import OrderedDict
# A set of descriptors for various types
class Typed:
_expected_type = type(None)
def __init__(self, name=None):
self._name = name
def __set__(self, instance, value):
if not isinstance(value, self._expected_type):
raise TypeError(fExpected str(self._expected_type))
instance.__dict__[self._name] = value
class Integer(Typed):
_expected_type = int
class Float(Typed):
_expected_type = float
class String(Typed):
_expected_type = str
# Metaclass that uses an OrderedDict for class body
class OrderedMeta(type):
def __new__(cls, cls_name, bases, cls_dict):
d = dict(cls_dict)
order = []
for name, value in cls_dict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
d[_order] = order
return type.__new__(cls, cls_name, bases, d)
def __prepare__(cls, cls_name, bases):
return OrderedDict()
class Structure(metaclass=OrderedMeta):
def Python从门到精通:文件处理-01-文件I/O