python面向对象之元类
元类
元类(A) ---> 类(B) ---> 实例(C)
对于实例C而言,它是对象,它的类就是类B
对于类B而言,它其实也是对象,那它的类就是元类A
对于元类A而言,它其实也是对象,那它的类就是自己本身
造类
第一阶段
class Foo:
count = 0
def __init__(self,name):
self.name = name
def eat(self):
print("eat")
def run(self):
print("run")
# ------------------------------------------
class_name = "Foo" # 类名
class_bases = (object,) # 继承类
class_body = """
count = 0
def __init__(self,name):
self.name = name
def eat(self):
print("eat")
def run(self):
print("run")
"""
class_dict = dict() # dict属性和方法
exec(class_body,{},class_dict) # 将class_bady中的字符串,转化为键值对存储到class_dict中
one = type(class_name,class_bases,class_dict) # 使用type创建类
print(one)
print(Foo)
<class '__main__.Foo'>
<class '__main__.Foo'>
这时,我们发现通过type创建出来一个和Foo相同的类one,但是这里的变量太死板了,我们还需要改变一下
第二阶段
class Foo(type):
def __init__(self,class_name,class_bases,class_dict):
if not class_dict.get("__doc__"):
raise TypeError("请加上注释")
super().__init__(class_name,class_bases,class_dict)
class person(object,metaclass=Foo):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def run(self):
print("run")
def eat(self):
print("eat")
one = person('plf',18,'男')
print(one.name)
print(one.age)
print(one.sex)
Traceback (most recent call last):
File "E:/***/***/***/test1.py", line 15, in <module>
class person(object, metaclass=Foo):
File "E:/***/***/***/test1.py", line 11, in __init__
raise TypeError("请加上注释")
TypeError: 请加上注释
因为我们在Foo类的__init__方法中对创建类的条件做了一些逻辑处理(如果类中没有注释,直接抛异常),解决的办法:第九行加上注释即可
class Foo(type):
def __init__(self,class_name,class_bases,class_dict):
if not class_dict.get("__doc__"):
raise TypeError("请加上注释")
super().__init__(class_name,class_bases,class_dict)
class person(object,metaclass=Foo):
'''我加上注释了'''
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def run(self):
print("run")
def eat(self):
print("eat")
总结:元类创建类,主要__init__方法中增加逻辑
造对象
NAME = 'PLF'
AGE = 18
class Foo(type):
def __init__(self,class_name,class_bases,class_dict):
self.count = 1
super().__init__(class_name,class_bases,class_dict)
def __call__(self, *args, **kwargs):
# 造空类
obj = object.__new__(self)
# 造对象
if len(args) == 0 and len(kwargs) == 0:
self.__init__(obj,NAME,AGE)
return obj
self.__init__(obj,*args,**kwargs)
return obj
class Person(object,metaclass=Foo):
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
print("run")
def eat(self):
print("eat")
def __call__(self, *args, **kwargs):
print("调用了")
# return self
one = Person('zhangsan',1000)
print('one对象的name:',one.name)
print('one对象的age:',one.age)
ori = Person()
print('ori对象的name:',ori.name)
print('ori对象的name:',ori.age)
one对象的name: zhangsan
one对象的age: 1000
ori对象的name: PLF
ori对象的name: 18
总结:通过元类造对象,操作的逻辑可以在__call__方法或者__new__方法中进行
python面向对象之元类的更多相关文章
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- Python面向对象之元类(metaclass)
点进来看就完事了铁汁!
- python基础——使用元类
python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
- [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式
使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...
- 什么是python中的元类
所属网站分类: python高级 > 面向对象 作者:goodbody 原文链接: http://www.pythonheidong.com/blog/article/11/ 来源:python ...
- Python中的元类(metaclass)
推荐+收藏:深刻理解Python中的元类(metaclass) 做一些笔记学习学习: 在大多数编程语言中,类就是用来描述如何生成一个对象的代码段,在Python中类也是一个对象,这个(类)对象自身拥有 ...
- Python面向对象之接口类(抽象类)
Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...
- [Python之路] 元类(引申 单例模式)
一.类也是对象 当我们定义一个变量或者函数的时候,我们可以在globals()的返回值字典中找到响应的映射: def A(): print("This is function A" ...
随机推荐
- jQuery中$.fn
$.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效. 如扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后面你的每一个 ...
- RTT学习之sensor设备
Sensor设备的常用操作: 首先查找传感器设置获取设备句柄.rt_device_find 以轮询.FIFO.中断.任意一种方式打开传感器,中断和FIFO需要设置接收回调函数(释放一个信号量给接收线程 ...
- 【PAT甲级】1085 Perfect Sequence (25 分)
题意: 输入两个正整数N和P(N<=1e5,P<=1e9),接着输入N个正整数.输出一组数的最大个数使得其中最大的数不超过最小的数P倍. trick: 测试点5会爆int,因为P太大了.. ...
- android studio中project structure配置
android studio project structure 1.project中填jdk路径 2.module中添androidsdk路径 3.sdks中填jdk路径
- mongodb副本集仲裁节点搭建
服务器准备: 主节点192.168.100.106 从节点192.168.100.107 仲裁节点192.168.100.108 三台服务器: 关闭防火墙 service iptables stop ...
- 路由器安全-NetFlow
1.NetFlow介绍 提供高层次的诊断,分类和识别网络异常. 使用NetFlow来检查哪些行为改变明显的攻击是非常有效的. 就像Wiretap一样捕获数据包. NetFlow像电话账单.(谁和谁在通 ...
- __str__()方法和__repr__()方法
有时候我们想让屏幕打印的结果不是对象的内存地址,而是它的值或者其他可以自定义的东西,以便更直观地显示对象内容,可以通过在该对象的类中创建或修改__str__()或__repr__()方法来实现(显示对 ...
- Copy-On-Write容器(转载)
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
- redis requires Ruby version >= 2.2.2 系统默认 ruby 版本过低,导致 Redis 接口安装失败
安装 Redis 接口时异常 ,系统 ruby 版本过低 ! 输入命令 " gem install redis " 出现 " ERROR: Error installi ...
- letter-spacing 与 word-spacing 结合使用,造成文字反转
文字未反转时,如图: 文字反转时,如图: 以上效果只是因为发现记录下来,目前并无实用,也许未来用得着它.