【问题标题】:Property setter with multiple values具有多个值的属性设置器
【发布时间】:2013-09-10 08:41:18
【问题描述】:

我有一个属性设置器,它通过获取两个字符串并对其进行哈希处理来生成一个唯一的 id:

@id.setter
def id(self,value1,value2):
    self._id = sha512(value1+value2)

我有两个问题:

  1. 是否允许(考虑到良好的 Python 编码实践)以这种方式编码
  2. 如何将两个值传递给 setter?

【问题讨论】:

    标签: python setter


    【解决方案1】:

    如何将两个值传递给 setter?

    你可以给setter传递一个iterable(tuple, list),例如:

    class A(object):
        def __init__(self, val):
            self.idx = val
    
        @property    
        def idx(self):
            return self._idx
    
        @idx.setter
        def idx(self, val):
            try:
                value1, value2 = val
            except ValueError:
                raise ValueError("Pass an iterable with two items")
            else:
                """ This will run only if no exception was raised """
                self._idx = sha512(value1+value2)
    

    演示:

    >>> a = A(['foo', 'bar'])     #pass a list
    >>> b = A(('spam', 'eggs'))   #pass a tuple
    >>> a.idx
    <sha512 HASH object @ 0xa57e688>
    >>> a.idx = ('python', 'org')  #works
    >>> b.idx = ('python',)         #fails
    Traceback (most recent call last):
        ...
        raise ValueError("Pass an iterable with two items")
    ValueError: Pass an iterable with two items
    

    【讨论】:

      【解决方案2】:

      setter 只能取一个值,所以使用一个元组:(value1, value2)

      @id.setter
      def id(self,value):          
          self._id = sha512(str(value))
      
      ...
      
      self.id = (value1, value2)
      

      (您没有发布sha512 是什么。我假设您使用的是hashlib.sha512,而sha512 正在调用update 方法,该方法需要一个字符串作为输入。)

      【讨论】:

        【解决方案3】:

        我对这里的编码做法有一些疑问。作为 API 的用户,我总是假设我设置为属性的任何内容都可以从同一个属性中取回。除此之外,有一个名为 id mutable 的东西看起来很可疑。

        至于传递两个值,怎么样:

        @id.setter
        def id(self, vals):
            value1, value2 = vals
            self._id = sha512(value1+value2)
        

        然后分配一个元组:

        myobj.id = (val1, val2)
        

        【讨论】:

          【解决方案4】:

          我不知道这是否是您想要的,但这是传递两个或更多值的另一种方式:

          @idx.setter
          def idx(self, args):
              self._idx = sha512(''.join([str(i) for i in args]))
          

          你可以避免列表或元组的限制:

          a.idx = 'zere', 'fezfz'
          a.idx = ("eddez", "erez")
          a.idx = 'deze', 'drezre', 'ezre'
          

          您必须在 init 中测试异常并处理异常。

          【讨论】:

            【解决方案5】:

            您也可以像这样使用property() 函数。

            from hashlib import sha512
            
            class U:
            
                def __init__(self, value1, value2):
                    self.id_setter(value1, value2)
            
                def id_getter(self):
                    return self._id
            
                def id_setter(self, value1: str, value2: str):
                value1, value2 = value1.encode(), value2.encode()
                self._id = sha512(value1+value2)
            
                id = property(id_getter, id_setter) # <----
            
            u = U("Foo", "Bar")
            print(u.id.hexdigest())
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-02-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-09
              • 2015-11-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多