【问题标题】:How to find a list of all **args of a function?如何查找函数的所有 **args 的列表?
【发布时间】:2015-10-31 03:42:35
【问题描述】:

如何找到一个函数的所有**args 的列表?

例如,我知道symbols()positive=Truereal=True 等作为参数,我想查看这些可能参数的完整列表。 但是,它们并未在 Sympy Core doc page 中列出。

我已经挖掘了源代码本身,但我无法追踪和定位我要查找的内容。

【问题讨论】:

  • 只是想知道这里的答案是否对您有所帮助,或者您是否需要任何特定方面的更多细节?
  • 是的,先生。听起来像假设模块是要看的地方。我特别感谢代码步行!很有启发性。我很容易在场边的座位上说这句话,但如果能在文档页面中记录这一点会很好。
  • 非常好 - 很高兴它有帮助。如果您认为答案已经解决了问题,请accept it. 我同意文档可以更明确地说“这是您可以传入的所有可能参数的完整列表”

标签: python sympy


【解决方案1】:

这些参数被命名为假设,可以在文档中找到: Sympy Assumptions

【讨论】:

    【解决方案2】:

    假设分类

    • 与简化符号相关,例如Q.positiveQ.even
    • 与代数场/环有关,例如Q.real, Q.complex.
    • 与一些事实有关,例如.is_boundedis_infinityis_zero 和 很快。它们帮助我们在核心中进行计算。 显然它们是从上述其他类派生的 假设(在启动对象时)(在这种情况下,例如 is_zero is 意味着它是环的零)。或者他们可以是 源自表达式的分析:在这种情况下,我们可以创建一些 计算的假设类别(在这种情况下 is_zero 可以是 意味着但是这种计算是困难的所谓的“零 测试”问题)。无论如何,我们可以意识到我们所处理的 确切地说(现在在我们使用 is_zero 在第二个意义上的核心某处)。

    假设示例:

    M ... Mathematica
    S0 ... SymPy, current approach
    S1 .... SymPy, approach 1
    S2 .... SymPy, approach 2
    
    M: Simplify[1/Sqrt[x] - Sqrt[1/x], x > 0]
    S1: x = Symbol('x', assumptions=IsPositive)
      simplify(1/sqrt(x) - sqrt(1/x))
    S2: simplify(1/sqrt(x) - sqrt(1/x), Assumptions(x>0))
    
    M: FunctionExpand[Log[x y], x > 0 && y > 0]
    S1: x, y = Symbol('x', assumptions=IsPositive), Symbol('y', assumptions=IsPositive)
     log(x*y).expand()
    S2: log(x*y).expand(Assumptions([x>0, y>0]))
    
    M: Simplify[Sin[n Pi], n \[Element] Integers]
    S1: n = Symbol('n', assumptions=IsInteger)
      simplify(sin(n*pi))
    S2: simplify(sin(n*pi), Assumptions(Element(n, Integer)))
    
    # we can talk about the syntax of Element(n, Integer)
    
    M: FunctionExpand[EulerPhi[m n], {m, n} \[Element] Integers && GCD[m, n] == 1]
    S1: n = Symbol('n', assumptions=IsInteger)
      m = Symbol('m', assumptions=IsInteger)
      n.assumptions.add(Eq(gcd(m, n) - 1))
      euler_phi(m, n)
    S2: euler_phi(m, n).expand(Assumptions([Element(n, Integer), Element(m, Integer), Eq(gcd(m, n) - 1)]))
    
    # again we can talk about the syntax of Element(n, Integer)
    
    M: RealQ[x, x \[Element] Real]
    S0: x = Symbol('x',real=True, integer=True)
      assert x.is_real == True
    S1:
    S2: assert IsElement(x, Real, assumptions=Element(x, Real))
    
    M: Refine[Abs[x], x>0]
       Refine[Abs[x], x0))
      print e.refine(Assumptions(x))
    

    更多参考资料:

    Wiki Sympi Assumptions

    Assuming

    Setting Assumptions on Variables in Sympy Relative to Other Variables

    Using SymPy's New Assumptions

    【讨论】:

      【解决方案3】:

      symbols()函数

      正如其他答案所指出的 - 在symbols 中使用**args 是传递关于正在创建的Symbol 的假设。您可以通过的假设列表在Assumptions 页面下记录为supported predicates

      不过,您还应该注意,可以传入一些其他特殊的命名参数。

      这些都记录在您链接的部分中,并且是:

      1. cls=<ClassName>

        尽管有它的名字,symbol() 可以创建类似符号的对象,例如 Function 或 Wild 类的实例。为此,请将 cls 关键字参数设置为所需的类型:

        注意如果未指定,则使用默认的Symbol 类。

      2. seq=<True|False>

        文档说:

        如果单个符号需要可迭代容器,请设置seq True 的参数或用逗号终止符号名称

      代码漫游

      您注意到您已经查看了代码 - 所以我将向您展示这些在代码中的实现位置。如果您调用symbols() 函数,它会对其参数进行各种检查,包括来自**argspop-ing cls and seq 参数,然后执行更多检查等,最后调用以实例化Symbol hereherehere。这些调用Symbol(或其通过cls 传入的子类)的构造函数,而**args 中剩下的所有内容都被解释为assumptions in the constructor. - 它们是sanitized here,即非假设或不适用的命名此时参数为thrown out

      这表明 Assumptions + cls + seq 形成了一组命名参数,可以在 **args 中传递给 symbols()


      其他功能(一般情况)

      在我看来,symbols() 可能只是作为一个更一般问题的代表性示例。我希望以上内容使您确信所有可以有效传递到symbols() 的值都已记录在案。这可能会让您确信 SymPy 中的其他函数也是如此。

      但是,在一般情况下,答案是很难向自己证明所有可以作为关键字参数传入的值都在 any 库或函数。实际上,有时只记录了一个子集,因为它们是库的“公共 API”,而实际代码可能需要其他参数,但由于某种原因,开发人员不想将它们公开给公众 - 例如因为它们的可用性可能会改变,或者它们的功能未经测试。

      如果您确实传递了无效参数,您使用的库的行为可能会有所不同。一些库或函数会忽略它们,而另一些库或函数会在您传入无效的关键字参数时抛出错误。

      如果您想了解是否是这种情况(并且该库是开源的,例如 SymPy),那么您可以随时深入研究代码(如我在上面的 Code Walk 中所示)。如果你这样做 - 你需要遵循执行路径,寻找 args.pop() 的出现。如果您担心 SymPy 中的其他功能,请在 cmets 中告诉我 - 但希望这种通用方法对您有用。

      我假设您了解*args**args 语法。如果这对您来说不是很清楚 - python official tutorial 的这一部分会处理它。

      【讨论】:

      • @Dietrich 因为您是提供赏金的人,所以我想知道您是否对特定的 symbols() 功能更感兴趣,或者您是否还有其他想要的东西我可以帮忙?
      • 非常感谢您的全面回答。假设页面的链接真的很有帮助。作为一个随意的 Sympy 用户(试图减少对 Mathematica 的沉迷),我在记住这些参数时遇到了问题,尤其是因为它们没有经过有效性检查:例如,symbols('x', pos=True) 不会引发错误(这不是一个很好的错误发现在一个人的代码中)。
      • 感谢您的评论和赏金。我同意——这类错误太可怕了。我不太喜欢 SymPy 仅通过 popping them and ignoring here 忽略不受支持的名称的方式。它本身并不是一个错误,但它确实使您提供的示例非常难以调试。
      【解决方案4】:

      您可以使用名为inspect 的内置python 库从任何函数中获取参数详细信息:

      import inspect
      inspect.getargspec(funcname)
      

      它将返回一个 ArgSpec 命名的元组,其中包含一些信息,例如:

      ArgSpec(args=['myarg'], varargs=None, keywords=None, defaults=(None,))
      

      要获取参数名称,您可以简单地访问该返回对象的args 属性。

      【讨论】:

      • 虽然这适用于命名参数 - 它不适用于 OP 正在寻找在 **args dict 中传递时有效的关键字参数列表的情况。您可以通过导入sympy 并执行inspect.getargspec(sympy.symbols) 来测试它。你得到ArgSpec(args=['names'], varargs=None, keywords='args', defaults=None),而不是可以在args中传递的所有值的列表
      猜你喜欢
      • 2014-04-28
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      相关资源
      最近更新 更多