Home > OS >  how should I change "__main__" str to run file that has if __name__=="__main__":
how should I change "__main__" str to run file that has if __name__=="__main__":

Time:12-25

I have many python files and sometimes I need to check them if they works. So they require different import ways in the file for libraries. The below code explains the situation.

I use else situations for fles that import XLS.

XLS.py

if __name__ == "__main__":
    import config
else:
    import DataLoaders.config as config


However I want to add dataset.py file to if situation.

if __name__ == "__main__" or __name__=="dataset.py":
    import config
else:
    import DataLoaders.config as config

I tried above code but it doesn't work. How to add the file name in if to import config file as demanded?

CodePudding user response:

Frequently this is better accomplished by either (though logically these end up the same because they both split import logic off)

  • splitting off functionality into separate files and importing it where needed
  • keeping all of the relevant logic together in a custom class or method of one

An example of this using @classmethod (which largely exists to aid this sort of design) could be

class MyClass:

    @classmethod
    def from_XLS(cls, xls_path):
        import custom_xls_loader
        data = custom_xls_loader.load(xls_path)
        # call any other other needed transform methods
        # opportunity to make result an instance of this class
        #   (otherwise why not use a normal function)
        return cls(data)

This is used for optional support in many large libraries (where there may be a huge number of busy dependencies that a user may not want or need to install for their use case)
Here's an example from Pandas where some Apache Arrow support is optional https://github.com/pandas-dev/pandas/blob/bbb1cdf13a1e9240b43d691aa0ec3ca1b37afee4/pandas/core/arrays/arrow/dtype.py#L112


Or in your case (referring to config as self.config in the class or as the .config property of an instance)

class MyClass

    def __init__(self, data, config=None)
        if config is None:
            import config
        self.config = config

    @classmethod
    def from_config_normal(cls, data):
        return cls(data)

    @classmethod
    def from_DataLoaders_config(cls, data):
        import DataLoaders.config as config
        return cls(data, config)

CodePudding user response:

__name__ is set to the name of the module, not whatever creates the module. So in XLS.py, its value is either "__main__", if the file is executed as a script, or XLS, if the module is imported by someone else.

The problem here is that config is, to some extent, a parameter for your module, whose value is determined elsewhere. (config, if you execute as a script, Databases.config if you import from dataset.py, maybe some other module if you import from elsewhere.)

Python, unfortunately, doesn't allow you to parameterize an import like you can a function. A workaround is to simply leave config undefined in XLS.py, and leave the caller the responsibility to set the value appropriately.

# XLS.py
...

if __name__ == "__main__":
   import config
   ...

# dataset.py
import XLS
import DataLoaders

XLS.config = DataLoaders.config
...

This works as long as XLS doesn't use config at import time; I assume it's just a name that other functions in the module may refer to when they are called.

CodePudding user response:

__file__ return the path of the python file that is currently running. You can use the fonction os.path.basename() to extract only the name of the file.

Here is an example:

import os

filename = os.path.basename(__file__)
print(filename)

It returns:

>>> test.py

You can then use a condition to check the name of the file and import the desired modules.

  • Related