【问题标题】:Calling a Python function without passing it an argument - animate(i)在不传递参数的情况下调用 Python 函数 - animate(i)
【发布时间】:2015-12-15 13:59:31
【问题描述】:

我正在努力弄清楚这段代码中发生了什么并对其进行调整以使我自己的代码能够正常工作。我不确定它是 Python 函数通用的东西,还是 matplotlib 动画包特有的东西。

代码来自Jake Vanderplas animation tutorial,但在网络上也有类似的例子。

这是被调用的动画函数:

# animation function.  This is called sequentially
def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

这是调用它的行:

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=200, interval=20, blit=True)

animate 接受参数i,但他调用它时没有变量ianimation.FuncAnimation 是否知道在其中传递一个值或者这是如何工作的?

顺便说一句——return 语句后面的逗号是否有意义?

【问题讨论】:

  • return line, == return (line,)
  • 最有可能的是,FuncAnimation 调用函数 animate 并将框架作为参数。那个“逗号”意味着返回是一个元组,如果它不存在,则返回将是一个变量。
  • 好的,谢谢,真的没想到,这是我第一次尝试动画,需要一些东西,以为可能是省略换行符,但显然不是。将阅读return语句必须多一点。..

标签: python function animation matplotlib


【解决方案1】:

当看到这样的案例时,最好记住 函数就像 Python 中的其他一切一样,是对象。因此,它们可以存储在数据结构中、重新分配名称并作为另一个函数参数传递

查看 animation.FuncAnimation 的文档:

class matplotlib.animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, **kwargs) 基础:matplotlib.animation.TimedAnimation

通过重复调用函数 func 并在 fargs 中传入(可选)参数来制作动画。

所以它只需要 函数对象 animate(在这种情况下)并使用 fargs 中提供的参数调用它(如果未指定,默认为 None)。

注意:查看FuncAnimation 的源代码后,我意识到fargs 只是附加参数 要传递给函数animate 和如果@987654332 @ 它们默认为空元组,表示没有参数。 (在这种情况下,fargs 不应该被指定,因为animate 只接受一个参数)

函数animate 使用以下方式调用:func(framedata, *self._args) 其中framedata 与最初传递的frames 参数相关,self._args 是通过fargs 提供的任何参数。

完整的调用(下面的self._func实际上是你的animate函数):

 # Call the func with framedata and args. If blitting is desired,
 # func needs to return a sequence of any artists that were modified.
 self._drawn_artists = self._func(framedata, *self._args)  

是的,matplotlib 在内部使用 framedata 参数调用您的函数。


作为return 中的尾随逗号,这意味着它将作为具有单个元素的元组返回值,在这种情况下为line。和下面的一样:

>>> i = 1,
>>> i
(1,)  # tuple with single element

【讨论】:

  • 谢谢你,y = np.sin(2 * np.pi * (x - 0.01 * i)) 期望 i 的值,但是,它与 None 有什么关系?
  • 如果您没有在fargs 中显式传递新值,它可能会引发TypeError,因为它将使用None。您需要为i 指定一个值,方法是在fargs 中传递它,例如fargs=10(例如)。
  • 感谢@Jim 的反馈,单元素的元组有助于查看。如果您检查网站jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial 上的代码,不幸的是没有fargs,我已经运行它,没有错误..
  • 好吧,我查看了源代码,它实际上传递了一个由 frames 参数构造的 iterable。它有点令人困惑,我认为你不需要在这里更深入。只要知道在内部它确实使用它构造的参数调用提供的函数 (animate) :-)。
  • 不不,如果i = () 那么0.1 * () 又是TypeError :-P。就像我说的,你的函数最终会被i = framedata 调用,这是固定的,不会改变。 (当您对 Python 感到有点熟悉时,请查看它的源代码,它将帮助您更详细地了解它是如何工作的,而不是我在回答中所能提供的。
【解决方案2】:

return 语句后面的逗号是否有意义?

是的,它是元组的简写语法,所以...
return line, == return (line,)

animation.FuncAnimation 是否知道在其中传递一个值,或者它是如何工作的?

我没有研究 matplotlib,但我认为你对它的语法感到困惑。可以将函数作为参数传入。见下文

def foo(func,x,y,z): # foo takes in func,x,y,z
    return func(z) # foo returns func(z)
    
def bar(a): # bar takes in a, return a*a
    return a*a
    
print foo(bar,2,3,4) # foo returns bar(4)

【讨论】:

    【解决方案3】:
    1. 在此调用中您传递函数引用,在 FuncAnimation 中,它可以使用正确的参数调用您的函数。
    2. 是的,它将响应作为元组。

    【讨论】:

      【解决方案4】:

      对于你问的部分,

      我不确定它是否适用于 Python 函数

      我邀请您阅读本教程的第二行。 http://www.diveintopython.net/getting_to_know_python/everything_is_an_object.html

      基本上,您在使用 Python 编程时需要牢记这一点,

      一切都是对象,可以像普通对象一样传递。

      这意味着类、函数、整数、字符串、列表、集合、元组......一切。因为如果你看到所有这些不同数据类型的基本类型,你会惊讶地发现,最基本的一切都是<type 'type'>

      延伸阅读:http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html#basic-concepts

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-10
        • 1970-01-01
        • 2019-07-13
        • 2018-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多