我有一个类Foo
,它包含一个数学比较运算op
作为字符串:'<','>'或'='。此外,Foo
包含一个数字val
。
class Foo:
def __init__(self, operation: str, value: int):
self.op = operation
self.val = value
在我的代码中,我从输入中读取一个数字,并使用Foo
的包含操作将其与Foo
的类示例值进行比较
f = Foo('<', 15)
to_check = int(input())
if f.op == '<':
if to_check < f.val:
# ...
elif f.op == '>':
if to_check > f.val:
# ...
elif f.op == '=':
if to_check == f.val:
#...
有什么方法可以做得更简单或更优雅吗?
这更优雅,效果也很好:
class Foo:
def __init__(self, op: str, val: int):
self.op = op
self.val = val
def check(self, other):
if isinstance(other, (int, float)):
if self.op == '<': return self.val > other
if self.op == '>': return self.val < other
if self.op == '=': return self.val == other
if self.op == '!=': return self.val != other
if self.op == '>=': return self.val <= other
if self.op == '<=': return self.val >= other
return NotImplemented
f.check(other)
检查包含操作的条件并返回,换句话说:
f = Foo('<', 15)
if f.check(14):
print('ok')
条件为True
,因为14
小于15
另一种选择:如果我在程序中使用Foo类,我想我会使用@S-c-a-t-c-h-y的方法。但这里有一种可能很优雅的方法,使用比较运算符的函数形式。
class Foo:
def __init__(self, operation: str, value: int):
self.op = operation
self.val = value
f = Foo('<', 15)
to_check = int(12)
import operator
op_dict = {
'>': operator.gt,
'<': operator.lt,
'==':operator.eq
}
op_dict.get(f.op)(to_check, f.val)
感谢您的回答,但我也考虑过将操作存储为lambda,而不是字符串。对于我的案例来说,这似乎不是一个糟糕的解决方案:
less = lambda x, y: x < y
equal = lambda x, y: x == y
f = Foo(less, 15)
to_check = 12
if f.op(to_check, f.val):
#...
这将适用于eval
。但必须小心使用eval
!请参阅本文,通过首先使用ast.literal_eval
进行解析来获得更安全的方法。在Python字符串中测试布尔表达式
更安全的方法可能不再被视为"安全";"更简单";或";更优雅";。
class Foo:
def __init__(self, operation: str, value: int):
self.op = operation
self.val = value
f = Foo('<', 15)
to_check = int(input())
eval(f'{to_check} {f.op} {f.val}')
Python已经内置了这个功能。我们可以覆盖
class Foo:
def __init__(self, operation: str, value: int):
self.op = operation
self.value = value
def __repr__(self):
return f"{self.__class__.__name__}({self.value} {self.op} input_X )"
def __lt__(self, input_value):
return self.value < input_value
def __le__(self, input_value):
return self.value <= input_value
def __eq__(self, input_value):
return self.value == input_value
def __gt__(self, input_value):
return self.value > input_value
def __ge__(self, input_value):
return self.value >= input_value
def check(self, input_value:int):
operations = {'<': self.__lt__,
'<=': self.__le__,
'==': self.__eq__,
'>': self.__gt__,
'>=':self.__ge__}
return operations.get(self.op)( input_value)
演示
f = Foo(">=", 15)
print(f)
# Foo(15 >= input_X )
f.check(14)
# True
f.check(16)
# False
f > 16
# False
f > 14
# True