Python从门到精通:元类-01-元类

Posted 生而为人我很遗憾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python从门到精通:元类-01-元类相关的知识,希望对你有一定的参考价值。

本章主要说一点高级的编程技巧,python中也算是比较常用的一种技巧--元类。有点类似于拦截器或AOP的功能。

一、控制类的创建

对象的类型叫作类,类的类型叫作元类。实例对象由类创建,而类则是由元类创建。类进行创建时会优先执行以下几个方法,通过复写这几个方法就可以控制类的创建过程,规范化代码,然后在类定义时使用metaclass来定义行为,以下三个方法会按顺序执行;

  1. __prepare__(定义类)
  2. __new__(实例创建之前)
  3. __init__(实例创建时)
  4. __call__(实例创建时)

1.1、基础

class NoInstances(type):
def __call__(self, *args, **kwargs):
raise TypeError("Cant instantiate directly")

# Example,这里最主要的是metacclass的运用
class Spam(metaclass=NoInstances):
@staticmethod
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):
@abstractmethod
def read(self, maxsize=None):
pass

@abstractmethod
def write(self, data):
pass


class MyMeta(type):
# Optional
@classmethod
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)

@classmethod
def __prepare__(cls, cls_name, bases):
return OrderedDict()


class Structure(metaclass=OrderedMeta):
def Python从门到精通:文件处理-01-文件I/O

Python从门到精通:Grpc实现

Python从门到精通:包装-03-对象处理

Docker 从门到精通一 数据卷的使用

python 的元类

python元类深入解析