【问题标题】:Class object can only call a method if object attribute is between a range如果对象属性在一个范围之间,类对象只能调用一个方法
【发布时间】:2020-09-13 02:52:31
【问题描述】:

我希望让我的代码更复杂,这就是我遇到的问题

class Person:

    def __init__(self, age):
        self.age = age

    def drives(self):
        if self.age >= 18:
            # Do more things which driving entitles
            print("you can drive")

    def studies(self):
        if self.age <= 25:
            # Do more student stuffs
            print("Good luck with your education")

bob = Person(14)
bob.drives()
bob.studies()

jim = Person(35)
jim.drives()
jim.studies()

我不喜欢一进入方法就进行检查,增加标记。我知道装饰器,它们是在这里做的最好的事情吗?我将如何将它们用于这个用例?我希望它看起来像:

class Person:

    def __init__(self, age):
        self.age = age

    @check_if_person_age_is_greater_than_17
    def drives(self):
        # Do more things which driving entitles
        print("you can drive")

    @check_if_person_age_is_less_than_26
    def studies(self):
        # Do more student stuffs
        print("Good luck with your education")

bob = Person(14)
bob.drives() # either this method cannot be accessed or returns nothing, since bob is 14
bob.studies() # this should work normally

jim = Person(35)
jim.drives() # this should work normally
jim.studies() # either this method cannot be accessed or returns nothing, since jim is 35

如果我的问题不够简洁或不值得,我很抱歉。

【问题讨论】:

  • 这只会让代码变得比它需要的更复杂
  • @rdas 是的。我想你是对的。我认为检查更好,因为它们使代码更具可读性

标签: python python-3.x oop object


【解决方案1】:

所以这就是我能够想出的。这会清理代码很多,但可能会使其有点难以理解。如果需要,您还可以将装饰器制作成类方法或静态方法。

from functools import wraps


def prerequisite(age_limit=18, _func=None):
  def _wrapper_function(func):
    @wraps(func)
    def _inner_function(*args, **kwargs):
        if args[0].age >= age_limit:
          return func(*args, **kwargs)
        else:
          raise ValueError("You can't {func_name} at the age of {age}".format(func_name=func.__name__, age=args[0].age))
    return _inner_function
  if _func is None:
      return _wrapper_function
  else:
      return _wrapper_function(_func)

class Person(object):
    def __init__(self, age):
      self.age = age

    @prerequisite(age_limit=16)
    def drive(self):
      # Do more drive stuffs
      print("You are eligible to apply for a license to drive. Please drive responsibly.")

    @prerequisite(age_limit=21)
    def drink(self, drink_name):
      # Do more drink stuffs
      # Passing an argument just to show that arguments can also be passed like this.
      print("You can legally drink. Alcohol is dangerous to health, drink cautiously. Your favorite drink is {drink_name}".format(drink_name=drink_name))

    @prerequisite()
    def fly(self):
      # Do more fly stuffs
      # This is an example for how default args for decorator works
      print("You are eligible to apply for a license to fly.")

bob = Person(19)

bob.drive() # works
bob.fly() # works
bob.drink("Beer") # This will throw an exception

【讨论】:

  • 在 Python 中实现类似 Java 的功能的有趣方式。我喜欢面向对象编码的应用。
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
相关资源
最近更新 更多