用其他无用的语句进行Duck键入(远程Pythonic)?
以下内容将引发浮点的TypeError用其他无用的语句进行Duck键入(远程Pythonic)?,python,python-3.x,duck-typing,Python,Python 3.x,Duck Typing,以下内容将引发浮点的TypeError from math import factorial def divide_factorials(a, b): return factorial(a) / factorial(b) >>> divide_factorials(6.1, 5) *** ValueError: factorial() only accepts integral values 这是完美的,直到我想合并一个优化 def divide_factoria
from math import factorial
def divide_factorials(a, b):
return factorial(a) / factorial(b)
>>> divide_factorials(6.1, 5)
*** ValueError: factorial() only accepts integral values
这是完美的,直到我想合并一个优化
def divide_factorials(a, b):
if a == b:
return 1
return factorial(a) / factorial(b)
现在我丢失了stop==start的float中的TypeError
>>> divide_factorials(3.3, 3.3)
1
我可以用isinstance返回我的TypeError,但这需要我确切地知道什么将在factorial(或我可能调用的任何其他函数)中工作,什么将不工作。这样做很有诱惑力
def divide_factorials(a, b):
# duck type first
factorial((a + b) % 1)
if a == b:
return 1
return factorial(a) / factorial(b)
这似乎更加稳健,但不那么明显。出于(我确信)充分的理由,我以前从未见过这种模式。不这样做的最佳理由是什么
我可以用assert或try/except来修饰它,但是
assert factorial((a + b) % 1) is not None
# or
try:
factorial((a + b) % 1)
except TypeError:
raise TypeError
如果说有什么区别的话,那似乎有点神秘。调用一个只用于执行类型验证的计算的函数确实很神秘。它使代码的意图不明确,因此使代码不符合python 如果重要的话,我只需重复相同的显式类型验证。此外,优化阶乘除法的正确方法是不调用阶乘函数,而是从除数加1迭代到被除数并聚合乘积:
def divide_factorials(a, b):
if not all(isinstance(i, int) for i in (a, b)):
raise TypeError('divide_factorials() only accepts integral values')
product = 1
for i in range(b + 1, a + 1):
product *= i
return product
“合并优化”。您是否测试了执行
返回阶乘(a)/阶乘(b)
需要多长时间?这是一个紧密的循环吗?“过早优化…”阶乘((5.5+4.5)%1)确实会产生一个值错误。这是我试图通过鸭子打字来避免的那种惊喜。但我确实同意你的观点,那是不清楚的。啊,我确实忘记了5.5+4.5
仍然会导致浮点数。我已经从我的答案中删除了这一点。你似乎要求所有的输入都是浮点数,而不是所有的输入都是整数。@user2357112oops这很明显。不知道我在想什么。谢谢。这确实需要a>=b。但我认为这是此类函数最明确、最明显的模式。