【问题标题】:Autoproperty failing in IronPython works in Python?IronPython 中的自动属性失败在 Python 中有效吗?
【发布时间】:2023-08-21 21:20:01
【问题描述】:

我有以下 python 代码,它在 python 中运行良好,但在 IronPython 2.6 中失败,出现以下错误,有什么想法吗?

    ======================================================================
ERROR: testAutoProp (__main__.testProperty)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "oproperty.py", line 66, in testAutoProp
    a.x = 200
  File "oproperty.py", line 31, in __set__
    getattr(obj, self.fset.__name__)(value)
AttributeError: 'A' object has no attribute '<lambda$48>'

----------------------------------------------------------------------
Ran 1 test in 0.234s

FAILED (errors=1)

这里是代码

#provides an overridable version of the property keyword
import unittest

#provides an overridable version of the property keyword

class OProperty(object):
  """Based on the emulation of PyProperty_Type() in Objects/descrobject.c"""

  def __init__(self, fget=None, fset=None, fdel=None, doc=None):
    self.fget = fget
    self.fset = fset
    self.fdel = fdel
    self.__doc__ = doc

  def __get__(self, obj, objtype=None):
    if obj is None:
      return self
    if self.fget is None:
      raise AttributeError, "unreadable attribute"
    if self.fget.__name__ == '<lambda>' or not self.fget.__name__:
      return self.fget(obj)
    else:
      return getattr(obj, self.fget.__name__)()

  def __set__(self, obj, value):
    if self.fset is None:
      raise AttributeError, "can't set attribute"
    if self.fset.__name__ == '<lambda>' or not self.fset.__name__:
      self.fset(obj, value)
    else:
      getattr(obj, self.fset.__name__)(value)

  def __delete__(self, obj):
    if self.fdel is None:
      raise AttributeError, "can't delete attribute"
    if self.fdel.__name__ == '<lambda>' or not self.fdel.__name__:
      self.fdel(obj)
    else:
      getattr(obj, self.fdel.__name__)()

def autoProperty( attrname, desc ):
  "Try to auto gen getters and setting for any property type"
  getFn = lambda self: getattr( self, attrname )
  setFn = lambda self, v: setattr( self, attrname, v )
  #set the corresponding function in the descriptor
  desc.fget = getFn
  desc.fset = setFn
  #if there is a blank colname let X property sort it out
  #if hasattr( desc, "colname") and desc.colname == "":
  #  i = 0
  #  while attrname[ i ] == "_":
  #    i = i + 1
  #  desc.colname = attrname[i:]
  return desc

class testProperty(unittest.TestCase):

  def testAutoProp(self):
    class A(object):
      def __init__(self):
    self._x = 50

      x = autoProperty( "_x", OProperty() )

    a = A()
    a.x = 200


if __name__ == "__main__":
  unittest.main()

【问题讨论】:

    标签: python lambda properties ironpython overriding


    【解决方案1】:

    仅查看您的代码和回溯,在我看来 IronPython 上的 lambda 具有诸如 &lt;lambda$48&gt; 之类的名称,而不仅仅是 &lt;lambda&gt;。这意味着您的测试 if self.fset.__name__ == '&lt;lambda&gt;' or not self.fset.__name__: 将采用错误的分支。

    试试:

    if self.fset.__name__.startswith('<lambda') or not self.fset.__name__:
    

    等等。

    【讨论】:

    • 感谢 Duncan,这完全有道理,刚刚修改了代码,测试现在可以工作了。干杯。乔恩。