簡體   English   中英

如何在Python中使用修飾符來指定和記錄方法的重復使用的參數?

[英]How can I use decorators in Python to specify and document repeated used arguments of methods?

我的一個類在許多重復的方法中都有一個邏輯numpy數組作為參數( idx_vector = None )。

如何使用裝飾器執行以下操作:

  1. 自動指定idx_vector
  2. 自動將描述插入文檔字符串

沒有裝飾器的示例:

import numpy as np
class myarray(object):
  def __init__(self, data):
    self.data = np.array(data) 

  def get_sum(self, idx_vector=None):
    """
    Input parameter:
      ``idx_vector``: logical indexing
    ...
    ... (further description)
    """
    if idx_vector == None:
      idx_vector = np.ones(len(self.data))
    return sum(self.data*idx_vector)

  def get_max(self, idx_vector=None):
    """
    Input parameter:
      ``idx_vector``: logical indexing
    ...
    ... (further description)
    """
    if idx_vector == None:
      idx_vector = np.ones(len(self.data))
    return max(self.data*idx_vector)

用法:

a = [1,2,3,4,5.0]
b = np.array([True, True, False, False, False])

ma = myarray(a)
print(ma.get_max())
# ----> 5.0
print(ma.get_max(b))
# ----> 2.0

我不確定我是否正確理解您。 如我所見,您的問題是您有很多函數都需要使用參數idx_vector ,並且您不想將其添加到每個參數列表中。 如果是這樣的話:

簡短的答案:您不能。

更長的答案:可以,但是函數需要某種方式來引用包含idx_vector的參數。 現在,您可以使用*args進行拾取,然后使用args[0]進行引用,但這並不能改變您仍然需要在每個函數中為將保存idx_vector的變量定義一些名稱的idx_vector

如何將idx_vectormyarray的屬性? 即, if self.idx_vector is not None

可以使用修飾符來修改函數的文檔字符串,但是請記住,如果每種情況下文檔字符串都不相同,則試圖將其抽象化就沒什么意義了。 而且,如果每個功能都相同,那不是很好的文檔! 但是,為示例起見,下面是代碼:

def addDocstring( func ):
    func.__doc__ = "Some description of the function."
    return func

裝飾器不是C預處理器的詞匯等效項,也不應該嘗試使它們成為這樣。 即使可以,建議的用法既隱含(因此每個PEP 20都是“丑陋的”),又非情報性的,這也違反了“如果實現難以解釋,那是個壞主意。”

更好的是:

import numpy as np
class myarray(object):
  """an array that has additional spam, eggs, and spam capabilities
     an idx_vector argument, if present, contains an mask for
     a subset the array, if not specified one will be created based 
     on the Frobnitz Conjecture"""
  def __init__(self, data):
    self.data = np.array(data) 

  def sum(self, idx_vector=None):
    """returns the sum of the elements of the array masked per idx_vector"""
    if idx_vector is None:
      idx_vector = np.ones(len(self.data))

  def max(self, idx_vector=None):
    """returns the largest element of the array masked per idx_vector"""

樣板注釋不好,因為它們降低了可讀性。 應該避免像get_這樣的冗余,因為它們是語法上的垃圾,這也會降低可讀性。 最后,如果myarray 另一個array 的一種形式,則可能要從該array繼承而不是對象。 如果您嘗試遵守某些要求的公司標准

"""
Input parameter:
  ``idx_vector``: logical indexing
..."""

然后標准就被打破了。

這導致一個相當不明顯的界面。 因此,除了玩游戲,我不建議將以下內容用於任何其他用途。 但是, 可以創建裝飾器來執行您要求的操作:

import numpy as np
import functools

def add_idx_vector(method):
    @functools.wraps(method)
    def wrapper(self, idx_vector=None):
        if idx_vector == None: idx_vector = np.ones(len(self.data))
        # This uses func_globals to inject a key,value pair into method's 
        # globals to spoof a default value.
        method.func_globals['idx_vector']=idx_vector        
        return method(self)
    wrapper.__doc__='''
        Input parameter:
          ``idx_vector``: logical indexing
        '''+wrapper.__doc__    
    return wrapper

class myarray(object):
    def __init__(self, data):
        self.data = np.array(data)

    @add_idx_vector
    def get_sum(self):
        '''(further description)
        '''
        return sum(self.data*idx_vector)

a = [1,2,3,4,5.0]
b = np.array([True, True, False, False, False])
ma = myarray(a)
print(ma.get_sum())
# ----> 15.0
print(ma.get_sum(b))
# ----> 3.0

這表明文檔字符串也已被修改:

help(ma.get_sum)
# Help on method get_sum in module __main__:

# get_sum(self, idx_vector=None) method of __main__.myarray instance
#     Input parameter:
#       ``idx_vector``: logical indexing
#     (further description)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM