【问题标题】:Python - use functions from another module in a functionPython - 在函数中使用来自另一个模块的函数
【发布时间】:2018-04-04 15:43:11
【问题描述】:

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

我正在尝试编写一个函数来比较一个向量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'

【问题讨论】:

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


    【解决方案1】:

    问题:

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

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

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

    你想做的是:

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

    【讨论】:

      【解决方案2】:

      @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]
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • @jseery 因为访问私有属性和函数是不好的做法
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-19
        • 1970-01-01
        • 2018-10-26
        相关资源
        最近更新 更多