tuple(mutabletuple)和collections.namedtuple(recordClass)的可变变量,支持赋值和更多内存保存变量(dataobject、litelist…)。

recordclass的Python项目详细描述


RecordClass库

怎么回事?

recordclass是由mit授权的。 它实现类型mutabletuple和工厂函数recordclass 为了创建类似记录的类——collection.namedtuple的可变变量 使用相同的api。稍后将添加更多节省内存的变体。

  • 可变元组是支持赋值操作的元组的可变变体。
  • RecordClass是一个工厂函数,它创建 集合.namedtuple。它生成一个子类mutabletuple和类似api的namedtuple。
  • structclass类似于recordclass。 它生成一个内存占用更少的类(少于两个基于recordClass的类实例 以及带有插槽的类实例 namedtuple类似于api。它的实例没有 \uu weakref\uu并且默认情况下不支持循环垃圾收集(仅引用计数)。 但是structclass创建的类可以支持任何一个类。
  • arrayClass是工厂函数。 它还生成一个内存占用率与structclass创建的类实例相同的类。 它实现了一个对象数组。默认情况下,创建的类没有 不支持循环垃圾收集。但它可以添加任何支持。

从0.10开始
  • dataobject是用于创建子类的新基类,它支持以下内容 属性默认为1)否和循环GC支持默认为禁用; 3)实例的内存大小小于具有\u插槽的类实例的内存大小
  • make_class是用于创建上述dataobject子类的工厂函数。

基于dataobject的类不遵循namedtuple-like api,而是遵循attrs/dataclasses-like api。 默认情况下,dataobject的子类不支持循环gc,而只支持引用计数。 因此,此类的实例需要较少的内存。 差异等于pygc_head的大小

未提供引用循环时,dataobject的子类是合理的。 例如,当所有字段都具有原子类型(整数、浮点、字符串、日期和时间等)的值时。 该字段的值也可以是dataobject的子类的实例(即,没有gc支持)。 作为一个例外,如果我们的实例不包含在这个对象中,那么字段的值可以是任何对象 以及它的子对象。

RecordClass库是作为快速"可变"问题的"概念证明"启动的 另一种选择named tuple(请参见关于stackoverflow的问题)。它的进一步发展是为了为数据对象的表示提供更多的内存节省、快速和灵活的类型。

RecordClass的主存储库 打开位桶

这里还有一个简单的示例

快速入门:

RecordClass快速入门

首次装载库存:

>>> from recordclass import recordclass, RecordClass

带有recordClass的示例:

>>> Point = recordclass('Point', 'x y')
>>> p = Point(1,2)
>>> print(p)
Point(1, 2)
>>> print(p.x, p.y)
1 2
>>> p.x, p.y = 10, 20
>>> print(p)
Point(10, 20)

带有recordclass和typehints::

的示例
class Point(RecordClass):
   x: int
   y: int

>>> ptint(Point.__annotations__)
{'x': <class 'int'>, 'y': <class 'int'>}
>>> p = Point(1, 2)
>>> print(p)
Point(1, 2)
>>> print(p.x, p.y)
1 2
>>> p.x, p.y = 10, 20
>>> print(p)
Point(10, 20)

使用dataobject快速入门

首次装载库存:>>> from recordclass import dataobject, asdict class Point(dataobject): x: int y: int >>> print(Point.__annotations__) {'x': <class 'int'>, 'y': <class 'int'>} >>> p = Point(1,2) >>> print(p) Point(x=1, y=2) >>> sys.getsizeof() # the output below is for 64bit python 32 >>> p.__sizeof__() == sys.getsizeof(p) # no additional space used by GC True >>> p.x, p.y = 10, 20 >>> print(p) Point(x=10, y=20) >>> print(iter(p)) [1, 2] >>> asdict(p) {'x':1, 'y':2}

另一种方法–工厂函数生成数据类

>>> from recordclass import make_dataclass

>>> Point = make_dataclass("Point", [("x",int), ("y",int)])

也支持默认值::

class CPoint(dataobject):
    x: int
    y: int
    color: str = 'white'

>>> Point = make_dataclass("Point", [("x",int), ("y",int), ("color",str)], defaults=("white",))

>>> p = CPoint(1,2)
>>> print(p.x, p.y, p.color)
1 2 'white'
>>> print(p)
Point(x=1, y=2, color='white')

可以缓存记录类和基于数据对象的类,以便在不重复的情况下重用它们:

from recordclass import RecordclassStorage

>>> rs = RecordclassStorage()
>>> A = rs.recordclass("A", "x y")
>>> B = rs.recordclass("A", ["x", "y"])
>>> A is B
True

from recordclass import DataclassStorage

>>> ds = DataclassStorage()
>>> A = ds.make_dataclass("A", "x y")
>>> B = ds.make_dataclass("A", ["x", "y"])
>>> A is B
True

记录类

recordClass的创建是为了回答python中存在可变命名元组的问题。

根据api、内存占用和速度,recordClass被设计和实现为几乎与namedtuple相同的类型,只是它支持可以在不创建新实例的情况下替换任何元素的赋值,如namedtuple(支持分配设置项。

namedtuple的有效性基于python中元组类型的有效性。为了达到同样的效率,创建了类型mutabletuple。结构(pymutabletupleobject)与元组的结构(pytupleobject)相同,因此占用的内存量与元组的内存量相同。

recordClass是在mutabletuple之上定义的,与tuple之上定义的namedtuple相同。通过描述符(itemgetset)访问属性,该描述符提供按属性索引快速访问和分配的功能。

recordclass生成的类看起来像::

from recordclass import mutabletuple, itemgetset

class C(mutabletuple, metaclass=recordobject):

    __fields__ = ('attr_1',...,'attr_m')

    attr_1 = itemgetset(0)
    ...
    attr_m = itemgetset(m-1)

    def __new__(cls, attr_1, ..., attr_m):
        'Create new instance of C(attr_1, ..., attr_m)'
        return mutabletuple.__new__(cls, attr_1, ..., attr_m)

等等,遵循namedtuple的定义方案

因此,recordclass占用的内存与namedtuple一样多,支持通过\u getitem\uu/\u setitem\uu和通过描述符协议的属性名快速访问。

结构类

在讨论中,我们正确地注意到,具有\u slots\uu的类实例也支持对对象字段的快速访问,占用的内存小于元组和使用factory函数recordclass创建的类实例。发生这种情况的原因是具有\u slots/code>的类实例不存储元素的数量,例如元组和其他元素(pyobjectvar),但它们将元素的数量和属性列表存储在其类型中(pyheaptypeobject)。

因此,创建了一个特殊的类原型,通过使用一个特殊的元类structclasstype,可以创建类,其实例在内存中的占用量与使用\u slots\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu/code>的类实例的占用量一样多,但根本不使用.基于此,factory函数structclass可以创建类,这些类的实例都类似于使用recordclass创建的实例,但占用的内存空间较少。

由structclass生成的类看起来像::

>>> from recordclass import recordclass, RecordClass
0

等等,遵循recordclass的定义方案

因此,基于structclass的对象占用的内存与基于slots的实例占用的内存一样多,并且还具有与创建的实例相同的功能。

比较

下表解释了recordclass-,recordclass2-基本对象的内存占用:

<表><广告>名称耦合 类/插槽 记录类结构类< /广告><正文>B+S+N*PB+N*PB+S+N*PB+N*P-G

其中:

  • b=sizeof(pyobject
  • s=sizeof(py\u ssize\t
  • n=项目数
  • p=sizeof(pyobject*
  • G=尺寸(PYGC头)

structclass的特殊选项cyclic_gc=false(默认情况下)允许禁用对循环的支持 垃圾收集。 在这种情况下,当您完全确定引用循环是不可能的时,这非常有用。 例如,当所有字段值都是原子类型的实例时。 结果实例的大小减少了24个字节:

>>> from recordclass import recordclass, RecordClass
1

这里还有一些性能计数器表:

<表><广告>< T/>名称耦合 类/插槽 记录类结构类< /广告><正文>新的739±24纳秒915±35纳秒763±21纳秒889±34纳秒getattr84.0±1.7纳秒42.8±1.5纳秒39.5±1.0纳秒41.7±1.1纳秒设置属性50.5±1.7纳秒50.9±1.5纳秒48.8±1.0纳秒

更改:

0.12.0.1

  • 修复丢失的.h文件。

0.12

  • clsconfig现在成为优化基于数据对象的类的主要装饰器。
  • 修复可变元组的连接(问题10)。

0.11.1:

  • dataobject现在可以更快地释放实例。

0.11:

  • memoryslots重命名为mutabletuple
  • 可变元组可变元组不参与循环垃圾收集。
  • 为不参与cyglic垃圾收集的类列表对象添加litelisttype。

0.10.3:

  • 介绍dataclassstorage和recordclassstorage。 它们允许缓存类并在不创建新类的情况下使用它们。
  • 添加iterabledecorator和参数。现在,默认情况下,带有字段的dataobject是不可iterable的。
  • astuple移动到dataobject.c

0.10.2

  • 修复dataobject的\u copy\uu的错误
  • 修复从0.8.5开始出现的记录类和结构类的pickling错误 (感谢康纳·沃尔夫)。

0.10.1

  • 现在默认情况下,如果dataobject有字段,那么默认情况下不支持序列协议, 但支持迭代。
  • 由于可用性原因,默认argsonly=false。

0.10

  • 为创建不同类型的数据对象类创建新的工厂函数 默认情况下不支持GC。
  • 创建新的元类datatype和新的基类dataobject以使用 语句。 它已禁用gc支持,但可以由decoratordataobject.enable\u gc启用。 它支持类型提示(对于python>;=3.6)和默认值。 当类型提示应用于所有 数据属性(对于python>;=3.6)。
  • 现在基于类的类可能也不支持循环垃圾收集。 这会将内存占用减少pygc_head的大小。 现在,默认情况下,基于recordClass的类不支持循环垃圾收集。
0.9
  • 将版本更改为0.9,表示向前迈进了一步。
  • 清除数据对象。

0.8.5

  • 使基于arrayclass的对象支持setitem/getitem和基于structclass的对象 不支持他们。默认情况下,与以前一样,基于structclass的对象支持setitem/getitem协议。
  • 现在只有dataobject的实例可以与基于"arrayclass"和structclass的实例相比较。
  • 现在生成的类可以散列化。

0.8.4

  • 改进对StructClass和ArrayClass只读模式的支持。
  • 为添加测试循环类。

0.8.3

  • 向基于structclass的类添加typehints支持。

0.8.2

  • 从类中删除usedictgcweaklist

0.8.1

  • 默认情况下,从源代码[问题7]中删除生成记录类的cython依赖项。

0.8

  • 添加structclassfactory函数。它类似于recordclass但内存较少 它在camparison中的实例(与带有\uu slots\uu的类的实例相同) 使用recordClassnamedtuple (目前使用cython实现。
  • 添加array classfactory函数,生成用于创建固定大小数组的类。 这种方法的好处还在于减少了内存占用 (目前使用cython实现。
  • structclassfactory现在有参数gc。如果gc=false(默认情况下)支持循环垃圾收集 将关闭已创建类的实例。
  • 添加函数join(c1,c2)以连接两个基于结构类的类c1和c2。
  • 添加sequenceproxy函数,用于从类实例创建不可变和散列的代理对象, 通过索引实现访问的 (目前使用cython实现。
  • 添加对按习惯用法访问RecordClass对象属性的支持:ob['attrname'](问题5)。
  • 将参数readonly添加到recordclass factory以生成不可变的namedtuple。 与collection.namedtuple不同,它使用的描述符与 提高性能的常规记录类。

0.7

  • 使可变元组对象创建更快。作为副作用:当字段数>;=8时 RecordClass实例创建时间不大于 带有\u插槽的数据类
  • RecordClass工厂函数现在以与3.7中的namedtuple相同的方式创建新的RecordClass类 (没有编译生成的python类源代码)。

0.6

  • 添加对RecordClass工厂函数中默认值的支持 与python 3.7中的namedtuple相同。

0.5

  • 将版本更改为0.5

0.4.4

  • 在RecordClass中添加对默认值的支持(来自Pedro von Hertwig的补丁)
  • 添加recorclass的测试(从namedtuple的python测试中采用)

0.4.3

  • 添加对python 3.6类型的支持(来自vladimir bolshakov的补丁)。
  • 解决内存泄漏问题。

0.4.2

  • 修复属性getter/setter中的内存泄漏

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java从文件扫描二维字符串数组   java SOAP请求xml内容作为字符串:prolog中不允许内容,并且文件过早结束错误   java从db类获取列表<string>,并存储在其他类中   java libgdx progressbar未显示在主屏幕上   如何正确地为在Java中的ArrayList中实现Compariable的对象实现方法?   在JavaSwing中删除JTable中的复选框   Web请求中的java默认地址:sendRedirect:绝对路径与相对路径   java找不到符号。正在查找超类而不是子类   java如何从开放位置代码获取完整代码   java在Android中有没有一种在seekbar上画线的方法?   java如何访问索引页?   java设置POI XWPFParagraph行间距   java在使用jCo(3.x))访问SAP表时未获取数据   使用POST客户端的java JSON字符串   Raspberry Pi3b+上嵌入的java JavaFX:在触摸屏上多次按下后,错误的按钮被激活   java控制操作的奇怪形式   maven java。lang.NoSuchMethodError:在。项目实体预订预订getOrCreateDayDetail   java注释HBM的长度是多少?   持久化实体对象时发生java Hibernate IllegalArgumentException:无法将字段“id”设置为实体对象?