用其他无用的语句鸭子打字(远程 Pythonic)?
Duck typing with otherwise useless statements (remotely Pythonic)?
下面将引发浮点数的 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_factorials(a, b):
if a == b:
return 1
return factorial(a) / factorial(b)
现在我丢失了 TypeError from floats where stop == start。
>>> 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
似乎有点神秘。
为了进行类型验证而调用一个旨在执行计算的函数确实很神秘。它使代码的意图不明确,因此使代码不符合 Pythonic。
如果它很重要,我会简单地重复相同的显式类型验证。此外,优化阶乘除法的正确方法是 而不是 调用阶乘函数,而是从除数加一迭代到被除数并聚合乘积:
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
下面将引发浮点数的 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_factorials(a, b):
if a == b:
return 1
return factorial(a) / factorial(b)
现在我丢失了 TypeError from floats where stop == start。
>>> 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
似乎有点神秘。
为了进行类型验证而调用一个旨在执行计算的函数确实很神秘。它使代码的意图不明确,因此使代码不符合 Pythonic。
如果它很重要,我会简单地重复相同的显式类型验证。此外,优化阶乘除法的正确方法是 而不是 调用阶乘函数,而是从除数加一迭代到被除数并聚合乘积:
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