Python 如何管理类的创建行为
问题
如果我们要给类加上一个属性,只需在定义的时候加上属性就可以了:
class Animal:
can_fly = True
如果这样的类有很多,我们可以定义一个父类,让其它类继承他就可以了:
class FlyAnimal:
can_fly = True
class Bird(FlyAnima):
pass
class Duck(FlyAnimal):
pass
...
要是不想显示的定义这些属性,只需要根据名字或其它属性来定义它的 can_fly 属性呢?(虽然这样的做法如同产品的需求一样 BT)这就可以用到元类了。
解决方案
通常情况下,我们先定义类,然后进行实例化。如果有了元类,那么类就相当于元类的实例——也就是说,先有元类,然后才有类。
因此,我们就可以创建元类来实现对类创建行为的控制。那么如何定义元类来实现需求呢?以上文的问题来,可以做如下定义:
class AnimalMetaclass(type):
def __new__(cls, name, bases, attrs):
if name.lower() in ['bird', 'duck']:
attrs['can_fly'] = True
return type.__new__(cls, name, bases, attrs)
class Animal(object, metaclass=AnimalMetaclass):
pass
class Bird(Animal):
pass
下面让我们来试试效果:
>>> Bird.can_fly
True
看起来非常成功!
扩展
- 元类需要继承自
type __new__方法接收的参数分别为:cls当前准备创建类的对象name类的名字bases类的父类集合attrs类的属性字典
- 使用元类时,通常会定义一个基类,用类指明元类,其它类继承自该基类即可
Python 如何管理类的创建行为的更多相关文章
- python 中动态类的创建
参考 collections.namedtuple 的实现 链接: https://www.cnblogs.com/BeautifulWorld/p/11647198.html
- python 多线程编程之threading模块(Thread类)创建线程的三种方法
摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...
- python之定义类创建实例
https://www.cnblogs.com/evablogs/p/6688938.html 类的定义 在Python中,类通过class关键字定义,类名以大写字母开头 1 2 >>&g ...
- python 通过元类控制类的创建
一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...
- 【python】-- 类的创建、__new__、__metaclass___
类的创建 前面的随笔都是关于类的知识,通过类创建对象,那这个类到底是怎么产生的呢? 1. 传统创建类 class Foo(object): def __init__(self,name): self. ...
- Android 性能优化(16)线程优化:Creating a Manager for Multiple Threads 如何创建一个线程池管理类
Creating a Manager for Multiple Threads 1.You should also read Processes and Threads The previous le ...
- python原类、类的创建过程与方法
今天为大家介绍一下python中与class 相关的知识-- 获取对象的类名 python是一门面向对象的语言,对于一切接对象的python来说,咱们有必要深入的学习与了解一些知识 首先大家都知道,要 ...
- python3 速查参考- python基础 8 -> 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)
基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self ...
- 细说python类3——类的创建过程
细说python类3——类的创建过程 https://blog.csdn.net/u010576100/article/details/50595143 2016年01月27日 18:37:24 u0 ...
随机推荐
- C# 复制目录及其下文件
public static void CopyDirectory(string sourceDirPath, string saveDirPath) { try { if (!Directory.Ex ...
- [cf1103E]Radix sum
类似于uoj272,即$B=10$的情况,然后有以下几个细节问题: 1.答案对$2^{58}$取模可以先使用自然溢出模$2^{64}$,最后对$2^{58}$取模即可 2.为了避免实数,令$\omeg ...
- [bzoj1046]上升序列
以i为开头的最长上升子序列,那么就是反过来以i为结尾的最长下降子序列,预处理出来后,不断向后找到下一个数即可 1 #include<bits/stdc++.h> 2 using names ...
- jmeter链接数据库,信息全部填写正确,运行之后没有结果
之前遇到一个很苦恼的问题,jmeter链接数据库,数据库填写的资料全部都没有问题,在其他电脑jmeter上都可以正常链接,但是在我的电脑上运行却总是不出结果, 用mysql链接数据库也一切正常,一直找 ...
- Redis高并发处理常见问题及解决方案
1. 大型电商系统高流量系统设计 场景: 大量电商系统每天要处理上亿请求,其中大量请求来自商品访问.下单.商品的详情是时刻变化,由于请求量过大,不会频繁去服务端获取商品信息,导致服务器压力极大.需要用 ...
- expr判断文件名以固定格式结尾
#!/bin/bash if expr "$1" : ".*\.sh" &>/dev/null then echo "okok" ...
- 日常Java 2021/10/1
正则表达式 \cx匹配由x指明的控制字符.例如,lcM匹配一个Control-M或回车符.x的值必须为A-Z或a-z之一.否则,将c视为一个原义的'℃'字符.\f匹配--个换页符.等价于\xOc和\c ...
- day33 前端之css
day33 前端之css css简介 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. # 语法结构 选择器 { 属性名1,属性值 属性名2,属性值 } # ...
- Learning Spark中文版--第三章--RDD编程(1)
本章介绍了Spark用于数据处理的核心抽象概念,具有弹性的分布式数据集(RDD).一个RDD仅仅是一个分布式的元素集合.在Spark中,所有工作都表示为创建新的RDDs.转换现有的RDD,或者调 ...
- Flink(三)【核心编程】
目录 一.Environment 二.Source 从集合读取数据 从文件读取数据 从kakfa读取数据(常用) 自定义数据源 三.Transform map Rich版本函数 flatMap key ...