【问题标题】:Pythonic use of class and module methodsPythonic 使用类和模块方法
【发布时间】:2013-07-12 01:31:16
【问题描述】:

我想这是一个初学者的问题,但我想知道当您遇到使用模块中定义的类中的类方法的情况时使用更 Pythonic 的方法,如以及在模块本身中定义的方法。我以numpy为例。

import numpy as np

foo = np.matrix([[3, 4], [9, 12]])

# Get norm (without using linalg)
norm = np.sqrt(foo.dot(foo.T)).diagonal()

我可以使用混合大小写,像这样,我调用 foo 的方法和 numpy 中定义的方法,或者我可以编写如下代码:

norm = np.diagonal(np.sqrt(np.dot(foo, foo.T)))

我自己更喜欢使用 foo.bar.baz.shoop.doop 语法,但在这种情况下我不能,因为 sqrt 不是 foo 的方法。那么,写这样一行的更 Pythonic 的方式是什么?

顺便问一下,与模块中定义的方法相比,类方法通常更优化吗?我不太了解幕后发生了什么,但我假设(再次以 numpy 为例)numpy 有一个 np.dot 方法,该方法是为 arg 可以是数组或矩阵的一般情况编写的,而 np.matrix.dot 仅针对矩阵运算重新实现和优化。如果我在这方面错了,请纠正我。

【问题讨论】:

    标签: python methods coding-style code-readability


    【解决方案1】:

    你问的问题并没有真正的答案,因为你问的案例根本不存在。

    通常,在 Python 中,您没有可用作方法和全局函数的相同函数。

    NumPy 是一种特殊情况,因为某些(但不是全部)顶级函数也可用作相应对象的方法。即便如此,它们通常也没有相同的语义,所以答案不是风格问题,而是哪一个是正确的功能。

    例如,在您的情况下,您唯一可以选择的是diagonal。这两个选项给出了不同的结果。

    >>> m = matrix([[1,2,3], [4,5,6], [7,8,9]]
    >>> np.diagonal(m)
    array([1, 5, 9])
    >>> m.diagonal()
    matrix([[1, 5, 9]])
    

    模块函数接受一个形状为 (N, N) 的二维数组并返回一个形状为 (N,) 的一维数组。该方法采用形状为 (N, N) 的二维矩阵,并返回形状为 (1, N) 的二维矩阵。

    matrix 方法可能会更快。但这并不像如果其中一个是正确的,另一个是错误的这一事实那么重要。这就像问+* 是否是两个数字相乘的更快方法。无论+ 是否比* 快,它都不是一种更快的乘法方式,因为它不会乘法。

    【讨论】:

    • 啊,我什至没有注意到不同的返回类型。事实上,这个特殊的例子,以及 Theano 中的一个类似例子,是我遇到的唯一例子。很高兴知道这不是一个常见的问题。它确实迫使我使用混合格式,就像我的第一个例子一样。如果不跟踪我的括号,我发现阅读起来有点困难,但这可以通过适当的评论来弥补。感谢你的回答。编辑:没有足够的声誉来投票:(
    • @Phox:请记住,您始终可以通过使用多个语句、使用中间变量(selfdot = np.dot(foo, foo.T),然后是norm = np.diagonal(np.sqrt(selfdot)))或将复杂的表达式转换为函数(norm = diagnorm(foo))来解决括号问题)。
    猜你喜欢
    • 2010-12-20
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2012-04-11
    • 2018-12-10
    • 2012-08-01
    相关资源
    最近更新 更多