大家可能很熟悉在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的更多相关文章

  1. Python 元类使用讲解

    我要一大群的类都具有一种特点,我怎么给他们加上呢?模板嘛,我从这个模板创建一群类不就OK了?那就需要元类了. 定义一个元类(就是一个类的模板!莫多想,还要记住这是类级别的,不是对象级别的!):代码如下 ...

  2. Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  3. python元类理解2

    恩,对元类理解又有新的收获,其实类似于装饰器,只不过装饰器是修饰函数,元类用来定制一个类. 代码如下,这是一个使用了函数做元类传递给类: input: def upper_attr(class_nam ...

  4. python元类:type和metaclass

    python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...

  5. python元类深入理解

    1.python 中的类 在python中,类也是一个对象,只不过这个对象拥有生成实例的能力,我们一般使用class XXX来定义一个类,在python解释器执行到这个地方的时候会自动创建出这个对象, ...

  6. [TimLinux] Python 元类

    1. type函数 name = "This is a string" print(type(name)) # <class 'str'> print("*& ...

  7. python 元类理解

    原文来自:https://segmentfault.com/a/1190000011447445 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生万物 我是谁?我从哪来里?我要到哪里去? ...

  8. Python元类之由浅入深

    前言 ​ 元类属于python面向对象编程的深层次的魔法,非常重要,它使我们可以更好的掌控类从创建到消亡的整个生命周期过程.很多框架的源码中都使用到了元类.例如 Django Framework 中的 ...

  9. Python 元类的基本介绍及使用

    一.什么是元类 二.如何使用元类 (一)不依赖class关键字创建一个自定义类 (二)自定义元类控制类的产生 (三)自定义元类控制类的调用 一.什么是元类 在python中,一切皆对象,而对象都是由类 ...

随机推荐

  1. RecyclerView, ListView 只显示一行内容 问题解决

    Adapter 中的data有多行,但是RecyclerView只显示一行. 原因出在item的layout xml, 用了自动生成的RelativeLayout, 她的默认高度height属性是ma ...

  2. url解析

    window.onload=function(){ var url="http://www.qq.com/index.html?key1=1&key2=2&key3=3&qu ...

  3. Windows Azure入门教学:使用Blob Storage

    对于.net开发人员,这是一个新的领域,但是并不困难.本文将会介绍如何使用Blob Storage.Blob Storage可以看做是云端的文件系统.与桌面操作系统上不同,我们是通过REST API来 ...

  4. Ext.Net学习笔记22:Ext.Net Tree 用法详解

    Ext.Net学习笔记22:Ext.Net Tree 用法详解 上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat=&q ...

  5. ###《High-level event recognition in unconstrained videos》

    Author: Yu-Gang Jiang, Shih-Fu Chang 事件检测的目标就是自动识别给定视频序列中的感兴趣事件.进行视频事件检测通常很困难,特别是在网络中非限制的视频.在非限制情况下, ...

  6. IOS开发之NSPredicate谓词的用法

    编程的人员不管是上过大学还是从培训机构出来的或做后台的.前端的都应该SQL语句有所了解,我们知道,在SQL语句当中 where 条件表达式可以对二维关系表的数据做条件筛选.微软的C# .net中也实现 ...

  7. WPF的TextBox的焦点获取与失去焦点的死循环解决方案

    在WPF中实现一个弹出层自动获取焦点,弹出层实现是通过其UserControl的依赖属性Visibility的绑定实现的,让UserControl上的TextBox获取焦点,初始实现代码如下: pub ...

  8. OC2_分数类

    // // Fraction.h // OC2_分数类 // // Created by zhangxueming on 15/6/10. // Copyright (c) 2015年 zhangxu ...

  9. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

  10. ubuntu下boost的配置方法

    boost版本为: boost_1_52_0ubuntu版本为:ubuntu-12.04.1-desktop-i386 这里有两种安装方法: =============第一种: 也是最简单的:进入li ...