簡體   English   中英

參數化多個子功能的最佳實踐

[英]Best practice for parametrizing multiple subfunctions

我經常遇到這樣的情況:我有一個頂層函數,希望從中修改多個子函數的任何參數。 我將用以下示例來表示:

def plot_data_processing(data_param_1=3, data_param_N=4,
        processing_param_1='a', processing_param_2='b', plotting_param_1='c',
        plotting_param_2=1324):
    data = get_data(data_param_1=data_param_1, data_param_1=data_param_N),
    processed_data = process_data(data, processing_param_1=processing_param_1, processing_param_2=processing_param_2)
    plot_data(processed_data, plotting_param_1=plotting_param_1, plotting_param_2=plotting_param_2)

現在,這有點丑陋,因為我被迫重新定義內部函數的所有默認值,而我的參數卻一團糟。 我想我可以做到以下幾點:

def plot_data_processing(data_kwargs, processing_kwargs, plotting_kwargs):
    data = get_data(**data_kwargs),
    processed_data = process_data(data, **processing_kwargs)
    plot_data(processed_data, **plotting_kwargs)

plot_data_processing(dict(data_param_1=3, data_param_N=4), dict(processing_param_1='a', processing_param_2='b'), dict(plotting_param_1='c',plotting_param_2=1324))

不過,這並不好,因為我正在做這種奇怪的做法,即通過dict傳遞參數,在該dict中,它們僅等待調用函數被驗證。 似乎像是關於錯誤和不可讀代碼的食譜。 另外,我沒有自由用相似的接口將內部調用的函數交換為不同的函數。 所以我也可以去:

def plot_data_processing(data_getter, data_processor, plotter):
    data = data_getter(),
    processed_data = data_processor(data)
    plotter(processed_data)

class DataGetter(object):
    def __init__(self, data_param_1=3, data_param_N=4):
        self.data_param_1 = data_param_1
        self.data_param_N = data_param_N
    def __call__(self):
        # ....
        return data

# ... Also define classes DataProcessor and Plotter

plot_data_processing(DataGetter(data_param_1=3, data_param_N=4), DataProcessor(processing_param_1='a', processing_param_2='b'), Plotter(plotting_param_1='c',plotting_param_2=1324))

但是,這似乎也涉及不必要的結構和絨毛代碼(self.x = x等)。 我可以通過使用局部變量(或lambdas)來解決這個問題:

def plot_data_processing(data_getter, data_processor, plotter):
    data = data_getter(),
    processed_data = data_processor(data)
    plotter(processed_data)

# Called like:
plot_data_processing(
    data_getter = partial(get_data, data_param_1=3, data_param_N=4),
    data_processor = partial(process_data, processing_param_1='a', processing_param_2=3),
    plotter = partial(plot, plotting_param_1='c', plotting_param_2=1342),
    )

但這似乎也不令人滿意-因為沒有明確的參數“類型”來調用該函數-只是部分函數在被調用時應該起作用-使得想要使用該函數的另一個程序員更加困難。

因此,這些方法都不會讓我感到滿足或高興。 我想我喜歡局部函數,但是我想以某種方式聲明局部函數服從某些接口。

有人知道更好的方法嗎?

Python 3.5有一個新的(可選)類型提示系統,可以完成您想要的操作。 Python解釋器不會在運行時檢查它,但確實允許您發出有關參數類型和返回函數值的語句。 可以在代碼上運行像mypy這樣的單獨的靜態分析器程序,以查找鍵入錯誤。

對於您的plot_data_processing函數,我想您要聲明如下內容:

from typing import Callable, TypeVar

DataType = TypeVar("DataType")
ProcessedDataType = TypeVar("ProcessedDataType") # could be the same as DataType

def plot_data_processing(data_getter: Callable[[], DataType],
                         data_processor: Callable[[DataType], ProcessedDataType],
                         plotter: Callable[[ProcessedDataType], None]) -> None:
    ...

如果data_processer函數使用與原始數據相同的類型返回相同的已處理數據,則可能只能使用一種DataType而不是兩種。 如果不需要通用方法,也可以更具體地指定這些類型(例如,使用Sequence[float]或其他方法,而不是使用TypeVar )。

有關更多詳細信息,請參見PEP 484和文檔typing模塊

暫無
暫無

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

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