How to instantiate an object once

318 views Asked by At

I am instantiating this object below every time I call csv in my function. Was just wondering if there's anyway I could just instantiate the object just once? I tried to split the return csv from def csv() to another function but failed.

Code instantiating the object

def csv():

    proj = Project.Project(db_name='test', json_file="/home/qingyong/workspace/Project/src/json_files/sys_setup.json")#, _id='poc_1'
    csv = CSVDatasource(proj, "/home/qingyong/workspace/Project/src/json_files/data_setup.json")
    return csv

Test function

def test_df(csv,df)

..............

4

There are 4 answers

0
Bruno Oliveira On BEST ANSWER

Is your csv function actually a pytest.fixture? If so, you can change its scope to session so it will only be called once per py.test session.

@pytest.fixture(scope="session")
def csv():
    # rest of code

Of course, the returned data should be immutable so tests can't affect each other.

0
ronakg On

You can store the object in the function's local dictionary. And return that object if it exists, create a new one if it doesn't.

def csv():
    if not hasattr(csv, 'obj'):
        proj = Project.Project(db_name='test', json_file="/home/qingyong/workspace/Project/src/json_files/sys_setup.json")#, _id='poc_1'
        csv.obj = CSVDatasource(proj, "/home/qingyong/workspace/Project/src/json_files/data_setup.json")
    return csv.obj
3
user4815162342 On

You can use a global variable to cache the object:

_csv = None

def csv():
    global _csv
    if _csv is None:
        proj = Project.Project(db_name='test', json_file="/home/qingyong/workspace/Project/src/json_files/sys_setup.json")#, _id='poc_1'
        _csv = CSVDatasource(proj, "/home/qingyong/workspace/Project/src/json_files/data_setup.json")
    return _csv

Another option is to change the caller to cache the result of csv() in a manner similar to the snippet above.

Note that your "code to call the function" doesn't call the function, it only declares another function that apparently receives the csv function's return value. You didn't show the call that actually calls the function.

0
Aaron Digulla On

You can use a decorator for this if CSVDatasource doesn't have side effects like reading the input line by line.

See Efficient way of having a function only execute once in a loop