gpt4 book ai didi

python - 我们如何在 Python 中一般地使用 sin、cos、tan(包括用户定义的类型)?

转载 作者:太空狗 更新时间:2023-10-29 20:23:19 25 4
gpt4 key购买 nike

编辑:让我尝试改写和改进我的问题。旧版本附在底部。

我正在寻找的是一种以类型通用的方式表达和使用自由函数的方法。例子:

abs(x)  # maps to x.__abs__()
next(x) # maps to x.__next__() at least in Python 3
-x # maps to x.__neg__()

在这些情况下,函数的设计方式允许具有用户定义类型的用户通过将工作委托(delegate)给非静态方法调用来自定义其行为。这很好。它允许我们编写不真正关心确切参数类型的函数,只要它们“感觉”像对某个概念建模的对象。

反例: 不能轻易通用的函数:
math.exp  # only for reals
cmath.exp # takes complex numbers

假设,我想编写一个通用函数,将 exp 应用于类似数字的对象列表。我应该使用什么 exp 函数?我该如何选择正确的?
def listexp(lst):
return [math.exp(x) for x in lst]

显然,即使有复数的 exp(在 cmath 中),这也不适用于复数列表。它也不适用于任何可能提供自己特殊 exp 函数的用户定义的类似数字的类型。

所以,我正在寻找一种在双方都解决这个问题的方法 - 理想情况下没有特殊的 shell 很多东西。作为一些不关心参数的确切类型的通用函数的作者,我想使用特定于所涉及类型的正确数学函数,而不必明确处理这个问题。作为用户定义类型的作者,我想公开特殊的数学函数,这些函数已经被增强以处理存储在这些对象中的附加数据(类似于复数的虚部)。

这样做的首选模式/协议(protocol)/习语是什么?我还没有测试 numpy .但是我下载了它的源代码。据我所知,它为数组提供了一个 sin 函数。不幸的是,我还没有在源代码中找到它的实现。但是看看他们如何设法为数组当前存储的正确类型的数字选择正确的 sin 函数会很有趣。

在 C++ 中,我会依赖于函数重载和 ADL(依赖于参数的查找)。由于 C++ 是静态类型的,因此在编译时完全处理此(名称查找、重载解析)也就不足为奇了。我想,我可以在运行时使用 Python 和 Python 必须提供的反射工具来模拟这一点。但我也知道,尝试将编码风格导入另一种语言可能是一个坏主意,而且在新语言中不太习惯。所以,如果你对方法有不同的想法,我会全力以赴。

我想,在某个时候,我需要以可扩展的方式手动执行一些依赖于类型的调度。也许编写一个模块“tgmath”(类型通用数学),它支持真实和复杂的支持,并允许其他人注册他们的类型和特殊情况函数......意见? Python 高手对此有何看法?

TIA

编辑:显然,我不是唯一对泛型函数和依赖于类型的重载感兴趣的人。有 PEP 3124但它自 4 年前就处于草案状态。

旧版问题:

我在 Java 和 C++ 方面有很强的背景,最近才开始学习 Python。我想知道的是:我们如何扩展数学函数(至少是它们的名称),以便它们适用于其他用户定义的类型?这些类型的函数是否提供我可以利用的任何类型的扩展点/钩子(Hook)(类似于迭代器协议(protocol),其中 next(obj) 实际上委托(delegate)给 obj.__next__ 等)?

在 C++ 中,我会简单地用新的参数类型重载函数,并让编译器找出使用参数表达式的静态类型的函数。但是由于 Python 是一种非常动态的语言,因此没有重载之类的东西。这样做的首选 Python 方式是什么?

另外,当我编写自定义函数时,我想避免长链
if isinstance(arg,someClass):
suchandsuch
elif ...

我可以使用哪些模式使代码看起来更漂亮和更 Python 化?

我想,我基本上是想解决 Python 中缺少函数重载的问题。至少在 C++ 中,重载和依赖参数的查找是良好 C++ 风格的重要组成部分。

是否可以制作
x = udt(something)  # object of user-defined type that represents a number
y = sin(x) # how do I make this invoke custom type-specific code for sin?
t = abs(x) # works because abs delegates to __abs__() which I defined.

工作?我知道我可以让 sin 成为类的非静态方法。但是后来我失去了通用性,因为对于所有其他类型的类似数字的对象,它是 sin(x)而不是 x.sin() .

添加 __float__方法是 Not Acceptable ,因为我在对象中保留了附加信息,例如“自动微分”的导数。

TIA

编辑:如果您对代码的外观感到好奇,请查看 this出去。在理想的世界中,我将能够以类型通用的方式使用 sin/cos/sqrt。我认为这些函数是对象接口(interface)的一部分,即使它们是“自由函数”。在 __somefunction我没有用 math. 限定函数也不是 __main__. .它只是有效,因为我手动回退到 math.sin (etc) 通过装饰器在我的自定义函数中。但我认为这是一个丑陋的黑客。

最佳答案

你可以这样做,但它会倒退。您实现 __float__()在您的新类型中,然后 sin()将与您的类(class)一起工作。

换句话说,您不会将正弦调整为在其他类型上工作;您调整这些类型,以便它们使用正弦。

这更好,因为它强制一致性。如果没有从对象到浮点数的明显映射,那么可能没有对 sin() 的合理解释。对于那种类型。

[抱歉,如果我之前错过了“__float__ 不起作用”部分;也许你是为了回应这个而添加的?无论如何,为了令人信服地证明你想要的东西是不可能的,python 有 cmath 库添加 sin()等复数...]

关于python - 我们如何在 Python 中一般地使用 sin、cos、tan(包括用户定义的类型)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7151776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com