Python 中的命名条件和一本愚蠢的教科书 - 以及如何证明它们是错误的
Named conditions in Python and a silly textbook - and how to prove they're wrong
Python 的抽象常常被许多人视为魔法。来自 C 背景,我很清楚没有魔法这样的东西,只有由产生抽象的简单组件组成的冷硬代码。
所以,当一本教科书和我的老师说我们可以“存储条件”或使用“命名条件”以提高可读性,并说将布尔表达式分配给变量突然使它成为类似于宏的动态条件,我输了。
编辑 1 :他们没有明确地说它像一个宏(直接引号放在引号内),因为我们不希望事先知道任何其他语言。
他们说“变量存储未计算的条件”的方式就像说它是一个宏,这是我的看法。他们通过表述暗示它实际上等同于宏,只是没有说 'macro'.
这个词
这是代码形式的声明:
x,y = 1,2
less = x < y
more = x > y
'''
less/ more claimed to store not boolean True/False but some magical way of storing the
expression itself (unevaluated, say like a macro) and apparently
'no value is being stored to less and more'.
'''
它被表示为好像一个人在做 :
// C-style
#define less (x < y)
#define more (x > y)
当然,这不是真的,因为所有less
和more
存储在所谓的'named conditions'只是运算符之间的return值x
和 y
.
这是显而易见的,因为 <
、>
、==
、<=
、>=
都具有布尔值 return正式手册页和规范以及 less
或 more
仅存储 True
或 False
布尔值 return 值,我们可以通过调用 print()
通过调用 type()
对它们 and/or。
此外,更改 x 和 y 的值,例如 x,y = y,x
不会更改 less
或 more
的值,因为它们存储的不是动态表达式而是静态表达式return >
或 <
操作数在初始 x
和 y
值上的值。
问题不在于这种说法是对所谓抽象的误解(它实际上不是抽象,类似的存储也可以在 asm 或 C 中实现),而是 如何清楚和有效地向我的老师表达,它不像 C 宏那样工作,而是静态存储 >
或 <
的布尔 return 值。
显然 less = x < y
只是查看 x
和 y
的当前值并将 True
或 False
存储到变量 less
.
如果我理解你和你的老师不同意的地方,你们两个对以下代码将打印出的内容有不同的想法:
x, y = 1, 2
less = x < y
print(less)
x, y = 2, 1
print(less)
“宏的”可以作为可以评估的文本字符串来实现,例如(错误的例子 - 不是推荐的解决方案):
less = "({0}) < ({1})"
并像这样使用它们:
x = 1
y = 3
outcome = eval(less.format("x", "y"))
但这确实是一件愚蠢的事情,而且 eval()
容易受到安全问题的影响。
也许你的老师打算使用 lambda expressions,这是无名的 ad-hoc 函数:
less = lambda a, b: a < b
x = 1
y = 3
outcome = less(x, y)
注:
standard library operator module 中已有 lambda a, b: a < b
可用的函数:operator.lt
。
Python 的抽象常常被许多人视为魔法。来自 C 背景,我很清楚没有魔法这样的东西,只有由产生抽象的简单组件组成的冷硬代码。
所以,当一本教科书和我的老师说我们可以“存储条件”或使用“命名条件”以提高可读性,并说将布尔表达式分配给变量突然使它成为类似于宏的动态条件,我输了。
编辑 1 :他们没有明确地说它像一个宏(直接引号放在引号内),因为我们不希望事先知道任何其他语言。
他们说“变量存储未计算的条件”的方式就像说它是一个宏,这是我的看法。他们通过表述暗示它实际上等同于宏,只是没有说 'macro'.
这个词这是代码形式的声明:
x,y = 1,2
less = x < y
more = x > y
'''
less/ more claimed to store not boolean True/False but some magical way of storing the
expression itself (unevaluated, say like a macro) and apparently
'no value is being stored to less and more'.
'''
它被表示为好像一个人在做 :
// C-style
#define less (x < y)
#define more (x > y)
当然,这不是真的,因为所有less
和more
存储在所谓的'named conditions'只是运算符之间的return值x
和 y
.
这是显而易见的,因为 <
、>
、==
、<=
、>=
都具有布尔值 return正式手册页和规范以及 less
或 more
仅存储 True
或 False
布尔值 return 值,我们可以通过调用 print()
通过调用 type()
对它们 and/or。
此外,更改 x 和 y 的值,例如 x,y = y,x
不会更改 less
或 more
的值,因为它们存储的不是动态表达式而是静态表达式return >
或 <
操作数在初始 x
和 y
值上的值。
问题不在于这种说法是对所谓抽象的误解(它实际上不是抽象,类似的存储也可以在 asm 或 C 中实现),而是 如何清楚和有效地向我的老师表达,它不像 C 宏那样工作,而是静态存储 >
或 <
的布尔 return 值。
显然 less = x < y
只是查看 x
和 y
的当前值并将 True
或 False
存储到变量 less
.
如果我理解你和你的老师不同意的地方,你们两个对以下代码将打印出的内容有不同的想法:
x, y = 1, 2
less = x < y
print(less)
x, y = 2, 1
print(less)
“宏的”可以作为可以评估的文本字符串来实现,例如(错误的例子 - 不是推荐的解决方案):
less = "({0}) < ({1})"
并像这样使用它们:
x = 1
y = 3
outcome = eval(less.format("x", "y"))
但这确实是一件愚蠢的事情,而且 eval()
容易受到安全问题的影响。
也许你的老师打算使用 lambda expressions,这是无名的 ad-hoc 函数:
less = lambda a, b: a < b
x = 1
y = 3
outcome = less(x, y)
注:
standard library operator module 中已有 lambda a, b: a < b
可用的函数:operator.lt
。