-1

I have a module named SSFbasis.py containing a function named SSFBasisFunc which looks like this:

if __name__ == '__main__':  
    def SSFBasisFunc(): 
        import os
        import re
        from pandas import ExcelWriter
  ......... etc.

I then have a MainScript.py where I have

import SSFBasis

a = SSFBasis.SSFBasisFunc()

and I get the error AttributeError: module 'SSFBasis' has no attribute 'SSFBasisFunc'.

Now, as I understand it, the name=main part in my function should prevent the code being executed on the initial import statement -- indeed this is what I want to happen.

But given I am then explicitly calling the function, shouldn't it be fine recognising the function, or am I misunderstanding the name == 'main': ?

** I am doing this using Spyder and Python 3.7 **

DMSTA
  • 212
  • 3
  • 9
  • You understand `__name__ == '__main__'` right. Your definition of `SSFBasisFunc` is never run so you can call it when you import it since it doesnt exist. – Loocid Jan 22 '19 at 08:26
  • To solve this problem, define the `SSFBasisFunc()` outside your `if __name__ == '__main__'`. The reason behind it is that the `if __name__ == "__main__"` part is executed only if you run the script itself, by the script I mean `SSFbasis.py` – Anwarvic Jan 22 '19 at 08:26
  • So, you can use `SSFBasisFunc()` only inside `SSFbasis.py` file not `MainScript.py`... I hoped this answered your question – Anwarvic Jan 22 '19 at 08:28
  • But you do want the code to run, otherwise the function is not defined... – SimonF Jan 22 '19 at 08:28

2 Answers2

1

TL;DR: define your exported values and functions outside of if __name__=='main.

You're currently defining SSFBasisFunc() inside the part of the script that doesn't get run when importing, so you can't access it in another script that begins by import SSFBasis.

The correct usage would be:

In SSFBasis.py:

def SSFBasisFunc():
    # define your function.
    # this part is not computationally intensive, because the function is only defined, not ran!

# optional, but usually a Python pattern
if __name__=="main":
    # define tests using SSFBasisFunc
    # might be computationally intensive

In another script:

import SSFBasis

# SSFBasis.SSFBasisFunc() is defined

You might also check what does if __name__=="main" do?

Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
  • I thought the name == main simply prevents the code being run on import but then if it was subsequently explicitly called it would be fine. Clearly that's not the case. Thanks for the help – DMSTA Jan 22 '19 at 08:58
0

Now, as I understand it, the name=main part in my function

It's not "in your function", it's before your function.

should prevent the code being executed on the initial import statement

To be more exact, tt prevents this part of the code from being executed when your module is imported (vs being executed as a script).

Now you don't really understand what this means. The code that this "prevents" from being executed is the def statement, which is the code that CREATES your function - not the function's code itself (which is only executed when the function is called).

IOW, with this condition, the SSFBasis function is defined ONLY when your file is executed as a script.

-- indeed this is what I want to happen.

Obviously not xD

But given I am then explicitly calling the function, shouldn't it be fine recognising the function,

At this point, this function does NOT exist - at all. It has not been defined. It's totally unknown. No one ever heard of it. It's missing. It's been lost in vacuum. It's been erased from the realms of reality. It's a non-function.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • My misunderstanding was exactly 'it prevents this part of the code from being executed when your module is imported'. I thought it was only on import statement and fine when explicitly called thereafter, but as you say, it does not exist. Many thanks – DMSTA Jan 22 '19 at 09:04