【问题标题】:AttributeError: Can't set attribute - How can I fix it?AttributeError:无法设置属性 - 我该如何解决?
【发布时间】:2021-02-11 12:22:44
【问题描述】:

我正在使用 pytest 开发测试,但遇到 AttributeError: can't set attribute

这是模型:

class User(UserMixin, db.Entity):
   _table_ = 'users'
   email = Required(str, unique=True)
   username = Required(str, unique=True)
   password_hash = Optional(str)
   pretax_income = Optional(Decimal, default=110000)
   tax_rate = Optional(Decimal, default=0.1)

   @property
   @db_session
   def monthly_income(self):
      return round(self.pretax_income/12, 2)

   @property
   @db_session
   def post_tax_income(self):
      return round(self.pretax_income - (self.pretax_income * self.tax_rate), 2)

  @property
  @db_session
  def post_tax_income_monthly(self):
      return round(self.post_tax_income / 12, 2)

这就是我做测试的地方,前两个工作正常。最后一个测试每月税后收入得到关于设置属性的错误。

class TestCalculator:

@db_session
def test_calc_monthly_income(self):
    user = User.get(email='test@test.com')
    user.pretax_income = 12000
    assert user.monthly_income == Decimal('1000')
    user.pretax_income = 48000
    assert user.monthly_income== Decimal('4000')

@db_session
def test_calc_post_tax_income(self):
    user = User.get(email='test@test.com')
    user.pretax_income = 120000
    user.tax_rate = 0.1
    assert user.post_tax_income == 108000
    user.pretax_income = 90000
    user.tax_rate = 0.2
    assert user.post_tax_income == 72000

@db_session
def test_calc_post_tax_income_monthly(self):
    user = User.get(email='test@test.com')
    user.post_tax_income = 36000
    assert user.post_tax_income_monthly == Decimal('3000')
    user.post_tax_income = 60000
    assert user.post_tax_income_monthly == Decimal('5000')

更新:我尝试以这种方式添加 setter。很明显,我做错了。

   @post_tax_income.setter
@db_session
def set_post_tax_income(self):
    self.post_tax_income = post_tax_income

【问题讨论】:

  • 您已将post_tax_income 定义为具有getter 而没有setter 的属性。所以只能获取,不能设置。

标签: python ponyorm


【解决方案1】:
@property
@db_session
def post_tax_income(self):
  return round(self.pretax_income - (self.pretax_income * self.tax_rate), 2)

这仅定义了一个 getter。它允许您获取值,但您不能这样做:

user.post_tax_income = 36000

这需要同时定义一个setter:

@post_tax_income.setter
def set_post_tax_income(self):
  ...

【讨论】:

  • 谢谢你,我明白你的意思了。我添加了以下内容,但仍然不确定问题出在哪里。这是我第一次使用 setter。
  • '''@post_tax_income.setter @db_session def set_post_tax_income(self): self.post_tax_income = post_tax_income
  • 这取决于您的程序。设置post_tax_income 甚至意味着什么?既然post_tax_income 似乎是一个计算属性,那么设置它是否有意义?也许您需要重新评估测试的编写方式
  • 对,它是一个计算属性。
  • 那你为什么要在测试中设置它?那应该达到什么目的?如果打算测试post_tax_income_monthly 方法,那么为什么不在测试post_tax_income 的同一个测试中这样做呢?即如果 post_tax_income 被验证,那么你也验证 post_tax_income_monthly 方法。那么你就不需要事先知道post_tax_income
猜你喜欢
  • 2015-02-08
  • 1970-01-01
  • 2014-08-09
  • 2020-10-07
  • 2019-04-14
  • 2018-08-30
  • 2017-07-17
  • 2014-04-06
  • 1970-01-01
相关资源
最近更新 更多