Python - 使用函数中另一个模块的函数

时间:2017-10-24 00:29:46

标签: python python-2.7 numpy scipy parameter-passing

我如何使用另一个模块中的一个或一组函数作为我自己的函数中的参数我定义?

我试图编写一个比较一个向量q的函数,并计算它与一组向量x中每个向量的距离。函数get_distances应采用一个向量q,向量集x和参数dist_methoddist_method应该从scipy.spatial.distance中进行任何一个距离计算并将其用于计算,所以我可以调用这样的函数:distances = get_distances(q, x, 'euclidean')这里是scipy参考页面 - get_distances应该可以使用任何距离函数braycurtis,canberra,...,sqeuclidean,wminkowski: https://docs.scipy.org/doc/scipy/reference/spatial.distance.html

在此函数所在的file1.py文件的顶部,我已导入scipy.spatial.distance,我认为我应该可以访问函数,例如distance.euclidean( ),但是当我在翻译中调用get_distances时,我得到AttributeError: 'module' object has no attribute 'dist_method'

我发现很多答案就像下面说的那样,功能是一流的对象'并且我应该能够像其他任何论点一样使用它们作为参数,并且我尝试过使用** kwargs概念,但我无法将它们全部放在一起。

有人能帮我理解我错过的东西吗?

KNN.py:

import numpy as np
import scipy.spatial.distance as dist

def get_distances(q, x, dist_method='euclidean', *args, **kwargs):
    """Query dataset to get distances for KNN

    Given a numpy array of vectors x and
    query point q, use dist_method to calculate
    distance from q to each vector in x

    Parameters:
        q: tuple
        x: numpy array
        dist_method (optional): distance function from scipy.spatial.distance

    Returns: list of distances
    """

    return [dist.dist_method(q, x_i) for x_i in x]

def load_samples():

    x = np.array([[1, 6],[2, 4],[3, 7],[6, 8],[7, 1],[8, 4]])

    y = np.array([[7],[8],[16],[44],[50],[68]])

    q = (4, 2)

    return x, y, q

这是我在翻译中所做的事情:

>>> import KNN as knn
>>> x, y, q = knn.load_samples()
>>> x
array([[1, 6],
       [2, 4],
       [3, 7],
       [6, 8],
       [7, 1],
       [8, 4]])
>>> d = knn.get_distances(q, x, 'cityblock')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "KNN.py", line 19, in get_distances
    return [dist.dist_method(q, x_i) for x_i in x]
AttributeError: 'module' object has no attribute 'dist_method'

3 个答案:

答案 0 :(得分:2)

问题:

return [dist.dist_method(q, x_i) for x_i in x]

是您尝试使用dist_method来访问名称与字符串值匹配的dist中的函数(即"euclidean"),但是dist.dist_method会查找"dist_method"对象中名为dist的函数,该函数不存在。

要按名称访问对象的函数,可以使用getattr,它将返回与字符串匹配的对象属性。

您想要做的是:

[getattr(dist,dist_method)(q, x_i) for x_i in x]

答案 1 :(得分:0)

@TheoretiCAL的回答显示了一种获得理想结果的方法,这是另一种方法:

methods = {
    'canberra': dist.canberra,
    'euclidean': dist.euclidean,
    # etc
}


def get_distances(q, x, dist_method=None, *args, **kwargs):
    method = methods.get(dist_method, dist.euclidean)
    return [method(q, x_i) for x_i in x]

答案 2 :(得分:-2)

问题是dist_method不是您尝试使用的模块中的任何内容的名称。您可以使用模块__dict__属性来&#34;获取&#34;适当的方法。

[dist.__dict__[dist_method](q, x_i) for x_i in x]