<legend id='ZwEcr'><style id='ZwEcr'><dir id='ZwEcr'><q id='ZwEcr'></q></dir></style></legend>

        <bdo id='ZwEcr'></bdo><ul id='ZwEcr'></ul>
        <tfoot id='ZwEcr'></tfoot>
      1. <i id='ZwEcr'><tr id='ZwEcr'><dt id='ZwEcr'><q id='ZwEcr'><span id='ZwEcr'><b id='ZwEcr'><form id='ZwEcr'><ins id='ZwEcr'></ins><ul id='ZwEcr'></ul><sub id='ZwEcr'></sub></form><legend id='ZwEcr'></legend><bdo id='ZwEcr'><pre id='ZwEcr'><center id='ZwEcr'></center></pre></bdo></b><th id='ZwEcr'></th></span></q></dt></tr></i><div id='ZwEcr'><tfoot id='ZwEcr'></tfoot><dl id='ZwEcr'><fieldset id='ZwEcr'></fieldset></dl></div>
      2. <small id='ZwEcr'></small><noframes id='ZwEcr'>

        对 Python 集类进行子类化、添加新实例变量的正确(或最佳)方法是什么?

        时间:2023-07-03
        <tfoot id='hTpdA'></tfoot>

            <bdo id='hTpdA'></bdo><ul id='hTpdA'></ul>
            • <i id='hTpdA'><tr id='hTpdA'><dt id='hTpdA'><q id='hTpdA'><span id='hTpdA'><b id='hTpdA'><form id='hTpdA'><ins id='hTpdA'></ins><ul id='hTpdA'></ul><sub id='hTpdA'></sub></form><legend id='hTpdA'></legend><bdo id='hTpdA'><pre id='hTpdA'><center id='hTpdA'></center></pre></bdo></b><th id='hTpdA'></th></span></q></dt></tr></i><div id='hTpdA'><tfoot id='hTpdA'></tfoot><dl id='hTpdA'><fieldset id='hTpdA'></fieldset></dl></div>
                  <tbody id='hTpdA'></tbody>

                <small id='hTpdA'></small><noframes id='hTpdA'>

                • <legend id='hTpdA'><style id='hTpdA'><dir id='hTpdA'><q id='hTpdA'></q></dir></style></legend>
                  本文介绍了对 Python 集类进行子类化、添加新实例变量的正确(或最佳)方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在实现一个与集合几乎相同的对象,但需要一个额外的实例变量,所以我将内置集合对象子类化.在复制我的一个对象时,确保复制此变量的值的最佳方法是什么?

                  I'm implementing an object that is almost identical to a set, but requires an extra instance variable, so I am subclassing the built-in set object. What is the best way to make sure that the value of this variable is copied when one of my objects is copied?

                  使用旧的 sets 模块,以下代码完美运行:

                  Using the old sets module, the following code worked perfectly:

                  import sets
                  class Fooset(sets.Set):
                      def __init__(self, s = []):
                          sets.Set.__init__(self, s)
                          if isinstance(s, Fooset):
                              self.foo = s.foo
                          else:
                              self.foo = 'default'
                  f = Fooset([1,2,4])
                  f.foo = 'bar'
                  assert( (f | f).foo == 'bar')
                  

                  但这不适用于内置的 set 模块.

                  but this does not work using the built-in set module.

                  我能看到的唯一解决方案是覆盖每个返回复制集合对象的单个方法......在这种情况下,我可能不会费心子类化集合对象.肯定有标准的方法可以做到这一点吗?

                  The only solution that I can see is to override every single method that returns a copied set object... in which case I might as well not bother subclassing the set object. Surely there is a standard way to do this?

                  (澄清一下,以下代码不起作用(断言失败):

                  (To clarify, the following code does not work (the assertion fails):

                  class Fooset(set):
                      def __init__(self, s = []):
                          set.__init__(self, s)
                          if isinstance(s, Fooset):
                              self.foo = s.foo
                          else:
                              self.foo = 'default'
                  
                  f = Fooset([1,2,4])
                  f.foo = 'bar'
                  assert( (f | f).foo == 'bar')
                  

                  )

                  推荐答案

                  我最喜欢的封装内置集合方法的方式:

                  My favorite way to wrap methods of a built-in collection:

                  class Fooset(set):
                      def __init__(self, s=(), foo=None):
                          super(Fooset,self).__init__(s)
                          if foo is None and hasattr(s, 'foo'):
                              foo = s.foo
                          self.foo = foo
                  
                  
                  
                      @classmethod
                      def _wrap_methods(cls, names):
                          def wrap_method_closure(name):
                              def inner(self, *args):
                                  result = getattr(super(cls, self), name)(*args)
                                  if isinstance(result, set) and not hasattr(result, 'foo'):
                                      result = cls(result, foo=self.foo)
                                  return result
                              inner.fn_name = name
                              setattr(cls, name, inner)
                          for name in names:
                              wrap_method_closure(name)
                  
                  Fooset._wrap_methods(['__ror__', 'difference_update', '__isub__', 
                      'symmetric_difference', '__rsub__', '__and__', '__rand__', 'intersection',
                      'difference', '__iand__', 'union', '__ixor__', 
                      'symmetric_difference_update', '__or__', 'copy', '__rxor__',
                      'intersection_update', '__xor__', '__ior__', '__sub__',
                  ])
                  

                  基本上与您在自己的答案中所做的事情相同,但 loc 更少.如果您也想对列表和字典做同样的事情,也很容易放入元类.

                  Essentially the same thing you're doing in your own answer, but with fewer loc. It's also easy to put in a metaclass if you want to do the same thing with lists and dicts as well.

                  这篇关于对 Python 集类进行子类化、添加新实例变量的正确(或最佳)方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:Python中set.discard和set.remove方法之间的运行时差异? 下一篇:如何在其比例变大时围绕其中心旋转图像(在 Pygame 中)

                  相关文章

                  <small id='ZbEkz'></small><noframes id='ZbEkz'>

                    <bdo id='ZbEkz'></bdo><ul id='ZbEkz'></ul>
                • <i id='ZbEkz'><tr id='ZbEkz'><dt id='ZbEkz'><q id='ZbEkz'><span id='ZbEkz'><b id='ZbEkz'><form id='ZbEkz'><ins id='ZbEkz'></ins><ul id='ZbEkz'></ul><sub id='ZbEkz'></sub></form><legend id='ZbEkz'></legend><bdo id='ZbEkz'><pre id='ZbEkz'><center id='ZbEkz'></center></pre></bdo></b><th id='ZbEkz'></th></span></q></dt></tr></i><div id='ZbEkz'><tfoot id='ZbEkz'></tfoot><dl id='ZbEkz'><fieldset id='ZbEkz'></fieldset></dl></div>

                    <legend id='ZbEkz'><style id='ZbEkz'><dir id='ZbEkz'><q id='ZbEkz'></q></dir></style></legend>

                  1. <tfoot id='ZbEkz'></tfoot>