Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建插槽对象实例性能_Python_Performance_Python Internals_Slots - Fatal编程技术网

Python 创建插槽对象实例性能

Python 创建插槽对象实例性能,python,performance,python-internals,slots,Python,Performance,Python Internals,Slots,我有一段代码,它使用值列表生成对象的实例。例如: 给定一个实现\uuuuuuuuuuuuuuuuuuuuu class A(object): __slots__ = ('a', 'b') 和一个值列表 >>> l = [1, 2] 我们通过 >>> o = A.__new__(A) >>> o <__main__.A object at 0x0617AE70> 我在许多值列表的循环中执行此操作,在分析我的程序之后,这是它

我有一段代码,它使用值列表生成对象的实例。例如:

给定一个实现
\uuuuuuuuuuuuuuuuuuuuu

class A(object):
  __slots__ = ('a', 'b')
和一个值列表

>>> l = [1, 2]
我们通过

>>> o = A.__new__(A)
>>> o
<__main__.A object at 0x0617AE70>
我在许多值列表的循环中执行此操作,在分析我的程序之后,这是它花费大量时间的地方。我想知道是否有更好的方法可以更快地使用普通python(没有pypy或cython)

注:

  • 我的程序实际上调用了
    cls.\uuuuu new\uuuu(cls)
    方法,该方法由我的
    \uuuu slots\uuu
    对象继承。因为我不知道调用该方法的类,所以这是我找到的创建该特定类类型的新实例的唯一方法
  • 我从一个包含值的文件创建这些对象,但这是程序的要求

    • 所以,我可以在那里有一些想法,但它们或多或少都是推测性的。 一个想法是使用命名元组,而不是直接的对象属性

      缺点是,除非您的类本身继承自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”变量用作可调用的构建 Python中的实例-与某些语言不同 其中需要文本类名称。 无需调用
      cls.\uuuu new\uuu
      并填充属性 “手动”。这将移动

      (另一方面,避免使用1个字母的变量名可以大大提高可读性,
      但是,如果您愿意这样做,您应该真正避免使用名称
      'l'
      ,因为它看起来就像
      '1'
      -我已经使用了上面的
      'attrs'

      另一种尝试是将值作为列表分配给对象,并在
      \uu getattribute\uuuu
      方法中惰性地处理对它们的访问。虽然这几乎肯定会让您在对象创建上节省时间,但它会将时间转移到第一个属性的使用上(但是,我不知道您是否真的必须访问所有对象上的所有属性-您可以微调您的策略)-如果这是一个问题,您将对内存使用产生巨大影响

      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
      

      这个项目的目的是什么?我很抱歉,但因为我不知道它是做什么的,代码是相当。。。难以理解。谢谢可能不会给您带来更高的性能-但这样做会更漂亮(“Pythonic”):对于attr,zip中的元素(o.uu插槽,l):setattr(o,attr,l)我猜您的问题太具体了。我认为它需要更多的上下文(可能太多了吧?)才能给你一个好的答案。@jsbueno我很喜欢你的“Pythonic”方法,因为它更容易阅读,但性能稍差一点(从快速基准测试来看大约是5%)。为什么你首先需要一个对象(一个
      a
      的实例)?Python可以使用简单的数据结构进行繁重的处理。而“面向对象”的方式往往会带来不必要的复杂性。我今天会尝试尝试一下,并向大家汇报。对于
      l
      名称问题,我实际上使用了更具描述性的名称,但在我的问题中,为了演示使用,我对它们进行了精简;这两种情况都很好。
      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