问题

如果我们要给类加上一个属性,只需在定义的时候加上属性就可以了:

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 如何管理类的创建行为的更多相关文章

  1. python 中动态类的创建

    参考 collections.namedtuple 的实现 链接: https://www.cnblogs.com/BeautifulWorld/p/11647198.html

  2. python 多线程编程之threading模块(Thread类)创建线程的三种方法

    摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...

  3. python之定义类创建实例

    https://www.cnblogs.com/evablogs/p/6688938.html 类的定义 在Python中,类通过class关键字定义,类名以大写字母开头 1 2 >>&g ...

  4. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  5. 【python】-- 类的创建、__new__、__metaclass___

    类的创建 前面的随笔都是关于类的知识,通过类创建对象,那这个类到底是怎么产生的呢? 1. 传统创建类 class Foo(object): def __init__(self,name): self. ...

  6. 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 ...

  7. python原类、类的创建过程与方法

    今天为大家介绍一下python中与class 相关的知识-- 获取对象的类名 python是一门面向对象的语言,对于一切接对象的python来说,咱们有必要深入的学习与了解一些知识 首先大家都知道,要 ...

  8. python3 速查参考- python基础 8 -> 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)

    基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self ...

  9. 细说python类3——类的创建过程

    细说python类3——类的创建过程 https://blog.csdn.net/u010576100/article/details/50595143 2016年01月27日 18:37:24 u0 ...

随机推荐

  1. [noi239]count

    将每一个ai表示为$ai=ki\cdot m+ri$,即满足$m\sum ki+\sum ri=n$且$0<ri<m$枚举$S=\sum ri$(S范围是$k\le S\le k(m-1) ...

  2. JavaScript 函数声明和变量声明

    声明语句:声明语句是用来声明或定义标识符(变量和函数名)并给其赋值. 1:var 变量声明(5.3.1节): var语句用来声明一个或多个变量:var name_1 = [= value_1] [ , ...

  3. Windows快捷键及cmd打开方式

    Windows快捷键 win+e 打开我的电脑 win+r 打开运行 ctrl+z 撤销 shift+del 彻底删除 alt+F4 关闭窗口 ctrl+c 复制 ctrl+a 全选 ctrl+x 剪 ...

  4. ARC128D

    考虑我们直接\(dp\). 那么需要快速的求出一段是否可以被消掉只剩两端. 我们可以考虑反过来做的. 我们知道如果全为\(abab\)型或者\(aa\)型则无法消掉 那么我们要前缀和,以及遇到\(aa ...

  5. Selenium-IDE,在网页上模拟人的操作

    想偷懒,不想做很机械重复的网页操作,就百度了一下看看有什么方法,能把自己从重复性的网页操作中解放出来,于是,百度到了selenium ide,折腾许久,用最新版火狐添加了自带selenium ide组 ...

  6. printf 的 转义词 -转

    \n    换行 \r    回车键 \b   退后一格 \f    换页 \t    水平制表符 \v   垂直制表符 \a   发出鸣响 \? 插入问号 \"    插入双引号 \'   ...

  7. 使用Postman轻松实现接口数据关联

    Postman Postman是一款非常流行的HTTP(s)接口测试工具,入门简单,界面美观,功能强大.作为一个测试/开发工程师,这是一款必须要会用的工具.今天以一个实际的案例,来介绍下Postman ...

  8. javaSE中级篇3——集合体系(另外一种存储容器)——更新完毕

    集合还是一种工具,所以它们的包都在java.util包下 1.集合的整个体系结构(是需要掌握的体系,完全体系不是这样) 对图中所说的 序和重复 这两词的说明: 序:指的是添加进去的元素和取出来的元素 ...

  9. abide, able, abnormal

    abide 近/反义词:1. 忍受: bear, endure, put up with, stand, tolerate2. 遵守(abide by): accept, comply, confor ...

  10. const与指针的三种形式

    使用指针时涉及到两个对象:该指针本身和被它所指的对象. 将一个指针的声明用const"预先固定"将使那个对象而不是使这个指针成为常量.要将指针本身而不是被指对象声明为常量,必须使用 ...