我有一段代码使用值列表生成对象的实例。例如:
给出一个实现__slots__
class A(object):
__slots__ = ('a', 'b')
和值列表
>>> l = [1, 2]
我们通过
创建对象的新实例>>> o = A.__new__(A)
>>> o
<__main__.A object at 0x0617AE70>
然后我们使用列表中的元素填充对象的属性
>>> for idx, element in enumerate(l):
... setattr(o, o.__slots__[idx], element)
>>> o.a
1
>>> o.b
2
我在许多值列表的循环中执行此操作,并且在对我的程序进行概要分析后,这是它花费了很多时间的地方。我想知道是否有更好的方法可以更快地使用普通的python(没有pypy或cython)。
注意:
cls.__new__(cls)
对象继承的方法调用__slots__
。由于我不知道调用该方法的类,这是我找到创建该特定类类型的新实例的唯一方法。答案 0 :(得分:2)
所以,我可以在那里有一些想法,但它们或多或少都是投机性的。 一个想法是使用命名元组,而不是直接对象属性。
缺点是,除非你的类本身继承了namedtuples(并且需要一些黑客攻击),否则你将在属性的路径中有一个额外的组件。
但他们,有些事情:
from collections import namedtuple
class MyClass42(object):
__slots__ = ["attrs"]
scheme = namedtuple("attrs", "attr1 attr2 attr3 attr4")
def __init__(self, attrs):
self.attrs = self.scheme(*attrs)
# and to create the classes:
o = cls(attrs)
# the downsides are that you have to access attributes like
o.attrs.attr1
# and all such attributes are imutable :-/
请注意,您可以使用“cls”var作为可调用来构建
Python中的一个实例 - 与某些语言不同
您需要文字类名称。
无需调用cls.__new__
并填充属性
“手动”。这将移动
(旁注,避免使用1个字母的变量名称可以提高可读性,
但是如果您愿意这样做,那么您应该避免使用名称'l'
,因为它看起来像'1'
- 我上面使用了'attrs'
答案 1 :(得分:1)
另一种尝试是将值作为列表分配给对象,并在__getattribute__
方法中懒惰地处理它们。虽然这几乎肯定可以节省您在对象创建中的时间,但它会将该时间转移到第一个属性使用(但是他们,我不知道您是否真的必须访问所有对象的所有属性 - 您可以微调您的策略) - 如果这是一个问题,你将对内存使用产生巨大影响。
class MyClass42(object):
__slots__ = ["raw_attrs", "attr1", "attr2", ...]
def __init__(self, attrs):
self.raw_attrs = attrs
def __getattr__(self, attr_name):
attr = self.raw_attrs[self.__slots__.index(attr_name) - 1]
setattr(self, attr_name, attr)
return attr