0

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?

  • 2
    `__name__` is a module name, not a file name. The purpose of the test is to distinguish between being imported and being executed as a script. Unless this code is in a file named `dataset.py`, it's not clear what you think `__name__ == "dataset.py"` would indicate. – chepner Dec 23 '22 at 19:03
  • Sorry. What I am trying to do is using if statement to import modules that is required by the file. `__name__ == "__main__"` rule is for file itself. I also want to add a new rule to if statement somehow that includes another file as the file itself. So both file itself and other specified file can use the modules that writen in if statement. In the above example, I want to make if statement valid for `dataset.py` file. So when I run `dataset.py` file it imports `config` file for `XLS.py` with if statement. – Alican Kartal Dec 24 '22 at 11:13
  • Because `XLS.py` throws error when I run `dataset.py` that use `XLS` file as an module that import `DataLoaders.config`. Is that clear enough? If so, I will add it to the question. Thanks for your help! – Alican Kartal Dec 24 '22 at 11:15
  • So if `dataset.py` imports `XLS` as a module? Sounds like the wrong file is trying to import `config` in that case. – chepner Dec 24 '22 at 14:07
  • Yes, it is correct. `else` statement for other files. Such as train.py, test.py etc. However I want to run `dataset.py` that import `XLS` that import directly `config` instead of `Dataloaders.config`. It is because `config`,`dataset.py` and `XLS` in same directory unlike `train.py` and `test.py`. So I wonder how to make `if statement` valid for `dataset.py`? – Alican Kartal Dec 24 '22 at 14:22
  • `__name__` won't help you; `XLS` doesn't know where it's being imported *from*. You should probably refactor your code so that `XLS` doesn't have a *static* dependency on any particular module. – chepner Dec 24 '22 at 14:24
  • I was hoping that `"__main__"` holds the name of the file that it is used, so it can be changed to name that is needed or in this case, dataset.py. I understand. Thanks for your help again. Should I delete or give negative point to question despite giving wrong information ? – Alican Kartal Dec 24 '22 at 14:31
  • Did you try putting `print(__name__)` in the code, and then running it under the conditions where you want the `if` block to be satisfied, in order to understand what value `__name__` will have (and therefore what you should check for)? I don't understand why there is a problem here that requires assistance from others. Please read [How much research is expected of Stack Overflow users?](https://meta.stackoverflow.com/questions/261592). – Karl Knechtel Dec 24 '22 at 16:38
  • Please also read [mre] and make sure that we can **copy and paste** the code from the question **without changing anything**, and **directly** see the **exact** problem described. For example: it sounds as if there is supposed to be another file `dataset.py` involved. Show an example of what that file could contain in order to demonstrate the problem (not any actual program logic, just enough to demonstrate the import problem), as well as the files that will be imported (with just test code to demonstrate the problem). Show the corresponding directory structure as well. – Karl Knechtel Dec 24 '22 at 16:41
  • Or did you mean "how can I tell which module is `import`ing the current one?"? In that case, you cannot, and should not want to. If different things should happen when different other modules `import XLS`, then they should import different versions of whatever "XLS" is, instead. If the goal is to treat `config` or `DataLoaders.config` as a *dependency* that is *injected into* the `XLS` code, there are entirely different techniques for that (for example, passing said module as an argument to the `XLS` functions). – Karl Knechtel Dec 24 '22 at 16:42
  • But overall: it is not at all clear what **concrete problem you are trying to solve**, nor what **concrete issue you are encountering**, so I cannot possibly write an answer. – Karl Knechtel Dec 24 '22 at 16:45

3 Answers3

1

__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.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

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)
ti7
  • 16,375
  • 6
  • 40
  • 68
0

__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.

Marin Nagy
  • 297
  • 1
  • 10
  • This is not I am looking for. Sorry for missunderstanding. I added extra information as a comment to @chepner. Thanks for your help! – Alican Kartal Dec 24 '22 at 11:17