简体   繁体   English

一遍又一遍地将相同的 dataframe 传递给 Python 中的不同类和函数

[英]Pass the same dataframe over and over again to different classes and functions in Python

The first step of my program is to get the data.我程序的第一步是获取数据。 After that I am finding myself passing this data to all the different classes (with also a config dictionary variable) over and over again.在那之后,我发现自己一遍又一遍地将这些数据传递给所有不同的类(还有一个配置字典变量)。

So I am wondering if there is a better way to just store the data somewhere and make it available to all classes and functions, without passing them as a parameter.所以我想知道是否有更好的方法将数据存储在某个地方并使其可供所有类和函数使用,而不将它们作为参数传递。

Thank you谢谢

Edit: here is a code example编辑:这是一个代码示例

go.py go.py

config = {
    'mode' : 'single',
    'data' : { },
    'strategy' : { },
    'view' : { }
}

stratego.start(config)

stratego.py策略.py

def start(config):

    data = dt.Data(config['data'])

    if (config['data']['type'] == 'yahoo'):
        df = data.get_yahoo_data()
    elif (config['data']['type'] == 'csv'):
        df = data.get_csv_data()
    else:
        return False

    trades = str.Strategy(df, config['strategy'])
    tradeBook = trades.run()

but then I am realising that the problem is my main function (start).但后来我意识到问题是我的主要 function(开始)。 If I run the main code not in a function I have all my instances available in the global.如果我不在 function 中运行主代码,我的所有实例都在全局中可用。 Is that right?是对的吗? Is it correct to do this way or it is better to wrap the program in a main function?这样做是正确的还是最好将程序包装在 main function 中?

If really you don't want to pass it as an argument you could define it as a variable in a python file and import this variable where you define your fonction.如果你真的不想将它作为参数传递,你可以将它定义为 python 文件中的变量,并在你定义函数的地方导入这个变量。 You should be able to use this variable in the function without passing it in argument.您应该能够在 function 中使用此变量,而无需将其传递到参数中。

EDIT: Refactored code according to code update by OP编辑:根据 OP 的代码更新重构代码

Ok since you use a strategy pattern you can actually do that using a strategy like design pattern好的,既然你使用了策略模式,你实际上可以使用像设计模式这样的策略来做到这一点

stratego.py

def start(*strategies):
    for strategy in strategies:
        strategy.run()

go.py

from functools import lru_cache, wraps
from abc import ABC, abstractmethod
import stratego

@lru_cache()
def get_data(filepath):
    # Load data from filepath
    data = ...
    return data

@lru_cache()
def get_data_with_config(**data_config):
    # Load data based on data_config
    data = get_data(data_config['filepath'])

    if (data_config['type'] == 'yahoo'):
        df = data.get_yahoo_data()
    elif (data_config['type'] == 'csv'):
        df = data.get_csv_data()
    ...
    return df

class Strategy(ABC):
    def __init__(self, config):
        self.config = config

    @abstractmethod
    def run(self):
        pass

class YahooStrategy(Strategy):
    def __init__(self, config):
        config = config.copy()
        config['data']['type'] = 'yahoo'
        super().__init__(config)

    def run(self):
        df = get_data_with_config(**self.config['data'])
        # Do sth with data

class CsvStrategy(Strategy):
    def __init__(self, config):
        config = config.copy()
        config['data']['type'] = 'csv'
        super().__init__(config)

    def run(self):
        df = get_data_with_config(**self.config['data'])
        # Do sth with data

class FunctionStrategy(Strategy):
    def __init__(self, config, func):
        super().__init__(config)
        self.func = func
    
    def run(self):
        return self.func(self.config)
    
def strategy_decorator(func):
    @wraps(func)
    def wrapper(config):
        return FunctionStrategy(config, func)
    return wrapper

@strategy_decorator
def some_strategy_function(config):
    df = get_data_with_config(**config['data'])
    # Do smth with data

# With one strategy
strategy = YahooStrategy({'data': {'filepath': 'data.csv', ...}})
stratego.run(strategy)

# Multiple strategies
strategies = [
    YahooStrategy({'data': {'filepath': 'data.csv', ...}}),
    CsvStrategy({'data': {'filepath': 'data2.csv', ...}}),
    some_strategy_function({'data': {'filepath': 'data4.csv', ...}})
]
stratego.run(*strategies)

If you're thinking pass by reference vs pass by value then I would suspect you are newer to Python. To my understanding, all variables are passed by reference.如果您正在考虑按引用传递还是按值传递,那么我怀疑您是 Python 的新手。据我了解,所有变量都是按引用传递的。 That is, you aren't copying the actual data every time you call a function with parameters.也就是说,每次使用参数调用 function 时,您都不会复制实际数据。

If you're thinking more along the lines of global variables, you can do something like this:如果您更多地考虑全局变量,则可以执行以下操作:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM