【问题标题】:Change Python's default logic when comparing strings [closed]比较字符串时更改 Python 的默认逻辑 [关闭]
【发布时间】:2021-07-02 17:27:43
【问题描述】:

有什么方法可以让 Python “认为” 5 > 6,或者其他一些任意数学/字符串方程以特定方式解释?

我主要想取一个带符号的字符串并自动使其大于另一个,以便"⇟" > "◈"计算为True

我知道您可以将这些符号分配给数字,但是如果有更简单的方法可以做到这一点,它可能会更有效。

这是我想要的基本概念:

firstSymbol = input("Type in a symbol: ")
secondSymbol = input("Type in a second symbol: ")
if firstSymbol > secondSymbol:
    print("firstSymbol > secondSymbol")
elif secondSymbol > firstSymbol:
    print("secondSymbol > firstSymbol")
elif firstSymbol == secondSymbol:
    print("Your two symbols are equal")

由于 Python 已经编写了类似的程序,我想对其进行更改,以便我可以创建大于或小于另一个符号的自己的符号,而不会中断 Python 的自动字符串比较。

【问题讨论】:

  • 我无法理解您希望通过这种方式完成什么。什么是“turtle.py”,它与数学有什么关系?
  • I am trying to make my own math equations without the interruption of python ... 看起来没有 math 的中断 :) 您可以编辑您的问题以更广泛地包含您想要做的事情吗?这可能是XY problem
  • 我假设你不能用用户定义的类来包装你的值,对吧?喜欢CustomInt(5) > CustomInt(6) is True
  • 您想在这里实现更一般的目标吗?有什么理由你不能只是扭转运营商? IE。 5 < 6 == True"a" < "the" == True?
  • Python 有很多方法可以在全局范围内或仅针对给定的模块/函数来破解它的部分功能。你可以做猴子补丁,你可以使用模拟库。对于自己的数据类型,您可以定义自己的运算符。但是,如果您不给出具体的示例代码 sn-p 并准确解释您想要实现的目标,您可能不会得到可以帮助您解决问题的答案

标签: python python-3.x string math symbols


【解决方案1】:

如果您定义自己的整数类,这相当简单:

class BadInteger(int):
    def __gt__(self, other):
        return super().__lt__(other)

print(BadInteger(5) > BadInteger(6))  # prints True

BadInteger 类基于 int 类(即常规 Python 整数)。但在这种情况下,我们通过重新实现__gt__ 特殊方法(“gt”代表“大于”)来反转“大于”比较的工作方式。该实现只是调用整数的__lt__(“小于”)实现。

这实际上意味着,当我们尝试使用> 比较两个BadIntegers 时,它就像我们将两个常规整数与< 进行比较一样。如果“大于”比较器将使用常规整数计算为 True,它现在将使用我们的 BadInteger 类计算为 False,反之亦然。

您仍然需要重新实现任何其他相关方法,以便它们以相反的方式工作(例如,__ge__ 用于“大于或等于”运算符 (>=),__lt__ 用于“小于”( <)等)。但这为实现您想要的目标奠定了基础。

编辑

由于您编辑了原始问题,因此这里有一个后续答案。

我们可以再次定义一个自定义类来实现您想要的功能。考虑一下:

class MySymbol:
    def __init__(self, symbol, value = None):
        if len(symbol) != 1:
            raise ValueError('Symbol string must have length 1')
        if value is None:
            value = ord(symbol)

        self.symbol = symbol
        self.value = value

    def __str__(self):
        return self.symbol

    def __repr__(self):
        return f'MySymbol(symbol={self.symbol}, value={self.value})'

    def __gt__(self, other):
        self.check_instance(other=other)
        return self.value > other.value

    def __ge__(self, other):

        self.check_instance(other=other)
        return self.value >= other.value

    def __eq__(self, other):
        self.check_instance(other=other)
        return self.value == other.value

    def check_instance(self, other):
        if not isinstance(other, MySymbol):
            error_message = (
               f"'==' not supported between instances of"
               f" '{self.__class__.__name__}' and"
               f" '{other.__class__.__name__}'"
            )
            raise TypeError(error_message)

MySymbol 类将一个符号和一个可选值作为输入。您可能已经看到这是怎么回事,但符号代表您的字符串,并且值是用于比较的数字。

由于我们实现了__gt____ge____eq__ 魔术方法,我们的符号“知道”如何使用>>=== 运算符相互比较,分别。

此外,Python 足够聪明,可以重复使用这些实现并简单地翻转结果 - 所以我们还可以免费获得 <<=!=

现在这可能不是完全您所希望的,因为我们仍然需要告知我们创建的每个符号的具体价值是什么。但这是创建自定义比较时要付出的代价——在您的程序中的某个时刻,您必须声明哪个自定义符号大于其他符号,反之亦然。 Python 永远不会“知道”你正在尝试以一种不寻常的方式比较事物,而你却从未告诉 Python 你想这样做。

快速演示:

firstSymbol = MySymbol('w', 30)
secondSymbol = MySymbol('$', 108)

firstSymbol != secondSymbol
# True

firstSymbol > secondSymbol
# False

# Note that it will use Python's default string values if we don't provide one
thirdSymbol = MySymbol('a')
fourthSymbol = MySymbol('b')

thirdSymbol > fourthSymbol  # same as comparing 'a' > 'b'
# False

并按照你的例子:

s1 = input("Type in a symbol: ")
v1_text = input("Type in its value: ")
try:
    v1 = int(v1_text)
except ValueError:  # use default string value
    v1 = None

s2 = input("Type in a second symbol: ")
v2_text = input("Type in its value: ")
try:
    v2 = int(v2_text)
except ValueError:  # use default string value
    v2 = None

firstSymbol = MySymbol(s1, v1)
secondSymbol = MySymbol(s2, v2)

if firstSymbol > secondSymbol:
    print("firstSymbol > secondSymbol")
elif secondSymbol > firstSymbol:
    print("secondSymbol > firstSymbol")
elif firstSymbol == secondSymbol:
    print("Your two symbols are equal")

示例输出:

Type in a symbol: !
Type in its value: 100
Type in a second symbol: #
Type in its value: 10
firstSymbol > secondSymbol

【讨论】:

    猜你喜欢
    • 2020-07-07
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 2013-01-06
    相关资源
    最近更新 更多