Python 中的所有内容都是对象,为什么运算符不是?
Everything in Python is an object, why operators are not?
Everything in Python is an object
我们都知道这句话,所有 Python 爱好者(包括我)都喜欢它。在这方面,看看运营商是很有趣的。它们似乎不是物体,例如
>>> type(*) # or /, +, -, < ...
returns SyntaxError: invalid syntax
。
但是,在某些情况下,将它们视为对象可能会很有用。例如考虑一个像
这样的函数
def operation(operand1, operand2, operator):
"""
This function returns the operation of two operands defined by the operator as parameter
"""
# The following line is invalid python code and should only describe the function
return operand1 <operator> operand2
所以operation(1, 2, +)
会return3
,operation(1, 2, *)
会return2
,operation(1, 2, <)
会return True
,等等...
为什么 python 中没有实施?或者是,如果,如何?
备注:我知道operator
模块,它也不适用于上面的示例函数。我也知道可以通过一种方式解决它,例如operations(operand1, operand2, '>')
并通过相应运算符的字符串表示找到所需的操作。但是,我要问的是不存在能够作为函数中的参数传递的运算符对象的原因,例如像所有其他 python 对象一样。
每个值都是一个对象。运算符不是值;它们是语法。然而,它们是由函数实现的,函数是值。 operator
模块提供对这些功能的访问。
完全不适用于 Python,尽管具有启发性,但语言 可以 提供额外的语法来将运算符转换为 "name"。例如,在 Haskell 中,您可以使用像 +
这样的中缀运算符,就好像它是一个使用括号的名称一样。你想在 Python 中写 operation(3, 5, +)
的地方, Haskell 允许 operation 3 5 (+)
.
没有 技术 不能将类似内容添加到 Python 的原因,但也没有令人信服的 设计添加它的原因。 operator
模块就足够了,"fits" 与整个语言设计更好。
运算符告诉解释器底层方法对提供的对象进行操作,所以它们更像函数,在某种意义上仍然是对象,你只需要适当的引用调用 type
。例如,假设您有 Foo.some_method
并且您想要查找它的类型。您需要正确的参考:type(Foo.some_method)
而不仅仅是 type(some_method)
,其中第一个 returns <class 'function'>
,后者 NameError
.
就是说,您当然可以在没有 operator
模块的情况下实现这样的功能:
def operation(operand1, operand2, operator):
return getattr(operand1, operator)(operand2)
operation(1, 2, '__add__')
# 3
也就是说,理解您的问题的最简单方法是运算符是 python 语法的一部分来解释您的代码,而不是实际对象。因此,当解释器看到 *
、+
、~
等时...它期望两个操作数获取别名方法并执行。方法本身是一个对象。语法,没那么多。
您可以将运算符视为一种语法糖。例如,3+4
只是 int.__add__(3,4)
的语法糖。 type(int.__add__)
不是 None 但 type(+)
会引发错误。
你说:
# The following line is invalid python code and should only describe the function
return operand1 <operator> operand2
这不是真的,该代码并非无效。使用配件 operator
,它确实按预期工作:
def operation(operand1, operand2, operator):
"""
This function returns the operation of two operands defined by the operator as parameter
"""
return operand1 <operator> operand2
class Subtraction:
def __gt__(self, operand):
try:
return self.operand - operand
except:
self.operand = operand
return self
print(operation(13, 8, Subtraction()))
按预期打印 5
。
这是一个很好的问题的例子。
从技术上讲,要正确回答这个问题,除了编码声明、注释和空行之外,还可以使用词法分析器(分词器)方法来区分分词类别。
除了运算符,还有:i) NEWLINE、INDENT 和 DEDENT,ii) 关键字,以及 iii) 定界符 不是对象。 其他所有内容都是 Python 中的对象。
所以下次他们告诉你“Python 中的一切都是对象”时你应该回答:
“逻辑行中除 NEWLINE、INDENT、DEDENT、Space bar Character、Operator、Keyword 或 Delimiter 之外的所有内容都是 Python 中的对象。”
这里的基本原理尝试:当 Python 设计者设计语言时,他们认为这些标记类别在任何情况下都几乎无用,无法通过其他方式解决。 .
干杯。
Everything in Python is an object
我们都知道这句话,所有 Python 爱好者(包括我)都喜欢它。在这方面,看看运营商是很有趣的。它们似乎不是物体,例如
>>> type(*) # or /, +, -, < ...
returns SyntaxError: invalid syntax
。
但是,在某些情况下,将它们视为对象可能会很有用。例如考虑一个像
这样的函数def operation(operand1, operand2, operator):
"""
This function returns the operation of two operands defined by the operator as parameter
"""
# The following line is invalid python code and should only describe the function
return operand1 <operator> operand2
所以operation(1, 2, +)
会return3
,operation(1, 2, *)
会return2
,operation(1, 2, <)
会return True
,等等...
为什么 python 中没有实施?或者是,如果,如何?
备注:我知道operator
模块,它也不适用于上面的示例函数。我也知道可以通过一种方式解决它,例如operations(operand1, operand2, '>')
并通过相应运算符的字符串表示找到所需的操作。但是,我要问的是不存在能够作为函数中的参数传递的运算符对象的原因,例如像所有其他 python 对象一样。
每个值都是一个对象。运算符不是值;它们是语法。然而,它们是由函数实现的,函数是值。 operator
模块提供对这些功能的访问。
完全不适用于 Python,尽管具有启发性,但语言 可以 提供额外的语法来将运算符转换为 "name"。例如,在 Haskell 中,您可以使用像 +
这样的中缀运算符,就好像它是一个使用括号的名称一样。你想在 Python 中写 operation(3, 5, +)
的地方, Haskell 允许 operation 3 5 (+)
.
没有 技术 不能将类似内容添加到 Python 的原因,但也没有令人信服的 设计添加它的原因。 operator
模块就足够了,"fits" 与整个语言设计更好。
运算符告诉解释器底层方法对提供的对象进行操作,所以它们更像函数,在某种意义上仍然是对象,你只需要适当的引用调用 type
。例如,假设您有 Foo.some_method
并且您想要查找它的类型。您需要正确的参考:type(Foo.some_method)
而不仅仅是 type(some_method)
,其中第一个 returns <class 'function'>
,后者 NameError
.
就是说,您当然可以在没有 operator
模块的情况下实现这样的功能:
def operation(operand1, operand2, operator):
return getattr(operand1, operator)(operand2)
operation(1, 2, '__add__')
# 3
也就是说,理解您的问题的最简单方法是运算符是 python 语法的一部分来解释您的代码,而不是实际对象。因此,当解释器看到 *
、+
、~
等时...它期望两个操作数获取别名方法并执行。方法本身是一个对象。语法,没那么多。
您可以将运算符视为一种语法糖。例如,3+4
只是 int.__add__(3,4)
的语法糖。 type(int.__add__)
不是 None 但 type(+)
会引发错误。
你说:
# The following line is invalid python code and should only describe the function return operand1 <operator> operand2
这不是真的,该代码并非无效。使用配件 operator
,它确实按预期工作:
def operation(operand1, operand2, operator):
"""
This function returns the operation of two operands defined by the operator as parameter
"""
return operand1 <operator> operand2
class Subtraction:
def __gt__(self, operand):
try:
return self.operand - operand
except:
self.operand = operand
return self
print(operation(13, 8, Subtraction()))
按预期打印 5
。
这是一个很好的问题的例子。
从技术上讲,要正确回答这个问题,除了编码声明、注释和空行之外,还可以使用词法分析器(分词器)方法来区分分词类别。
除了运算符,还有:i) NEWLINE、INDENT 和 DEDENT,ii) 关键字,以及 iii) 定界符 不是对象。 其他所有内容都是 Python 中的对象。
所以下次他们告诉你“Python 中的一切都是对象”时你应该回答:
“逻辑行中除 NEWLINE、INDENT、DEDENT、Space bar Character、Operator、Keyword 或 Delimiter 之外的所有内容都是 Python 中的对象。”
这里的基本原理尝试:当 Python 设计者设计语言时,他们认为这些标记类别在任何情况下都几乎无用,无法通过其他方式解决。 .
干杯。