Python元类实践--自己定义一个和collections中一样的namedtuple
大家可能很熟悉在collections模块中有一个很好用的扩展数据类型-namedtuple。
如果你还不知道这个类型,那么请翻看标准手册。
我利用元类轻松定义一个namedtuple。
先把代码贴上,满足心急的朋友。
def myNamedTuple(tuple_name, attrs_str):
attrs_set = set(attrs_str.split(' '))
def __init__(self, attrs): #我们将来实例初始化的时候需要调用的方法。
for key, value in zip(attrs_set, set(attrs)):
self.__dict__[key]=value
def __str__(self): #这个只是方便打印用的。
values = [str(x) for x in self.__dict__.values()]
return tuple_name+'(' + ', '.join(values) + ')'
def to_dict(self): #提供一个to_dict()方法,用来把我们的命名元组转为字典。
return self.__dict__
#调用type来建立类。
#第二个参数指定其继承自元组。
#第三个参数指定我们需要存入的属性名(也就是__dict__的键名,然后就是上面定义的方法。
return type(tuple_name, (tuple,),{'attr_keys':attrs_set,'__init__':__init__,'__str__':__str__,'to_dict':to_dict})
if __name__=='__main__':
Point = myNamedTuple('Point','x y')
p = Point([1,2]) #目前我们的参数只能传入一个,否则报错,这是和namedtuple之间的差别。
print(p)
print(type(Point),p, sep='\n')
print(p.x,'---',p.y)
print(p[0],p[1])
print(p.to_dict)
p +=(4,) #此时已经变成了普通的tuple了。内置的namedtuple也是一样。
print(type(Point),p, sep='\n')
实现方法
其实,Python的内部也是创建了一个继承自tuple的类。
>>> from collections import namedtuple
>>> Rectangle=namedtuple('Rectangle', 'height width')
>>> r = Rectangle(3,4)
>>> type(r)
<class '__main__.Rectangle'>
建立一个列表用来存储所有需要存入的健。在将来实例化调用__init__
方法的时候,我们再来建立实例的__dict__
属性字典。
至于取值,那么就是类调用实例的__dict__
了。
如果看不明白的,请先看我关于元类介绍的那一讲。
改进
由于我们的类继承自元组,而元组默认只能传入一个可迭代对象。
那么我们修改一下原来的代码,让我们的myNamedTuple也可以像namedtuple一样可以接受多个参数。
def myNamedTuple(tuple_name, attrs_str):
class Meta(type): #定义一个元类,采用`__call__`方法来拦截类的实例化,在实例化之前我们先把位置参数全部转入一个叫args的元组中,然后在调用type的`__call__`方法,从而把刚才的元组传进去,这样就只有一个参数了,从而无论你传入多少个位置参数,在这个步骤之后,只会出现一个参数了,成功!
def __call__(self, *args):
return type.__call__(self, args)
attrs_set = set(attrs_str.split(' '))
def __init__(self, args):
for key, value in zip(attrs_set, set(args)):
self.__dict__[key]=value
def __str__(self):
values = [str(x) for x in self.__dict__.values()]
return tuple_name+'(' + ', '.join(values) + ')'
def to_dict(self):
return self.__dict__
return Meta(tuple_name, (tuple,),{'attr_keys':attrs_set,'__init__':__init__,'__str__':__str__,'to_dict':to_dict})
if __name__=='__main__':
Point = myNamedTuple('Point','x y')
print(Point)
p = Point(1,2) #多个参数成功调用....
print(p)
print(type(Point),p, sep='\n')
print(p.x,'---',p.y)
print(p[0],p[1])
print(p.to_dict)
p +=(4,) #此时已经变成了普通的tuple了。
print(type(Point),p, sep='\n')
如果有什么不懂的,请留言。
如果这个例子通了,那么collections中的其他数据类型是不是也是一样的道理呢?
Python元类实践--自己定义一个和collections中一样的namedtuple的更多相关文章
- Python 元类使用讲解
我要一大群的类都具有一种特点,我怎么给他们加上呢?模板嘛,我从这个模板创建一群类不就OK了?那就需要元类了. 定义一个元类(就是一个类的模板!莫多想,还要记住这是类级别的,不是对象级别的!):代码如下 ...
- Python进阶丨如何创建你的第一个Python元类?
摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...
- python元类理解2
恩,对元类理解又有新的收获,其实类似于装饰器,只不过装饰器是修饰函数,元类用来定制一个类. 代码如下,这是一个使用了函数做元类传递给类: input: def upper_attr(class_nam ...
- python元类:type和metaclass
python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...
- python元类深入理解
1.python 中的类 在python中,类也是一个对象,只不过这个对象拥有生成实例的能力,我们一般使用class XXX来定义一个类,在python解释器执行到这个地方的时候会自动创建出这个对象, ...
- [TimLinux] Python 元类
1. type函数 name = "This is a string" print(type(name)) # <class 'str'> print("*& ...
- python 元类理解
原文来自:https://segmentfault.com/a/1190000011447445 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生万物 我是谁?我从哪来里?我要到哪里去? ...
- Python元类之由浅入深
前言 元类属于python面向对象编程的深层次的魔法,非常重要,它使我们可以更好的掌控类从创建到消亡的整个生命周期过程.很多框架的源码中都使用到了元类.例如 Django Framework 中的 ...
- Python 元类的基本介绍及使用
一.什么是元类 二.如何使用元类 (一)不依赖class关键字创建一个自定义类 (二)自定义元类控制类的产生 (三)自定义元类控制类的调用 一.什么是元类 在python中,一切皆对象,而对象都是由类 ...
随机推荐
- svn管理代码在cornerstone上无法添加.a 静态库文件
有时候.a静态库不能上传到svn的服务器 导致别人拉代码运行不了 这是因为cornerstone设置里面默认不会提交.a文件, 在上图选项栏里是cornerstone默认忽略上传的文件名后缀,在这里 ...
- GitHub帮助文档翻译1——helloWorld
工欲善其事必先利其器 ,都不知道 GitHub到底是什么,还怎么玩?因为总是会读了第一句就忘了下一句,形成不了感觉,所以希望把读GitHub的帮助文档都翻译出来,总是看大段大段的东西,谁都会懵圈的.希 ...
- Hive UDAF介绍与开发
UDAF简介 UDAF是用户自定义聚合函数.Hive支持其用户自行开发聚合函数完成业务逻辑. 通俗点说,就是你可能需要做一些特殊的甚至是非常扭曲的逻辑聚合,但是Hive自带的聚合函数不够玩,同时也还找 ...
- 电脑小白自学软件编程-.Net语法基础之循环语句,纯技巧干货
写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用视频. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是不在话下. 本教程是基础教程,适合任何有志于学习软件开发的 ...
- .Net 动态代理,AOP
.Net 动态代理,AOP 直接上代码了. /***************************************** * author:jinshuai * * E-mail:redfox ...
- 【JDK源码系列】ConcurrentHashMap
并发永远是高性能的话题,而并发容器又是java中重要的并发工具,所以今天我们来分析一下Concurrent包中ConcurrentHashMap(以下简称Chashmap).普通容器在某些并发情况下的 ...
- .Net Core 学习 (1) - ASP.NET Core 总览
什么是ASP.NET 1.0 开源 - GitHub 跨平台 - 支持Windows, Mac, Linux 从底层进行了优化 - 使用最小开销的模块化组件 - 给与了开发人员很大的灵活性 为什么要使 ...
- C#学习笔记4:关键词大小写、复合格式化等
1.取消选择的单选按钮值 RadioButton1.Checked=RadioButton2.Checked = false;//RadioButton1.Text = RadioButto ...
- selenium简单代码入门
#!/usr/bin/env python #-*- coding:utf-8 -*- import os,sys,string import time import unittest from se ...
- selenium文件上传的实现
一.对于上传文件, 从手动操作我们可以看出, 需要对window 窗体进行操作, 而对于selenium webdriver 在这方面应用就受到了限制. 但是, 庆幸的是, 对于含有input ele ...