Here you have the required information.
My function fnEXP contains:
You seem to be conflating functions with files. There is no need to have
these functions each in their own file. You’ll be a lot better off
having a single file defining your various functions unless there’s some
special reason to break things up.
With everything in a single file there’s no need to import names.
def fnEXP():
class MyException(PermissionError):
import logging
logging.error('MyException classified!')
Alexander has already mentioned this, and it has also been mentioned
before. This function fnEXP
defines a local class named
MyException
. And then discards it (as any local variable is
descarded when you leave a function).
Also, that class is only defined when fnEXP
is actaully called/run.
The file containing fnEXP
only defines the fnEXP()
function. It
does not call it.
Usually you’d define a class as a top level name. In your case, you
might make the contents of the fnEXP
file just this:
class MyException(PermissionError):
import logging
logging.error('MyException classified!')
Which would define MyException
at the module level, immediately.
There’s no need for the fnEXP()
function, as to my eye it does not not
anything else. So it can be discarded.
My function fn3 contains:
from fnEXP import fnEXP
fnEXP()
This is an odd way to do things (and ineffective, as you discover
later). It looks like you’re calling the fnEXP()
function in order to
define the MyException
class. But because that class is a local
variable in the fnEXP()
function, it is forgotten as soon as you
return from the function, and was never visible outside the function
anyway.
If you change the fnEXP
file as suggested above, to just define the
MyException
class at the top level, and drop the fnEXP()
function
completely, you’ll end up with a module level MyException
name.
And when you’ve done that you can go:
from fnEXP import MyException
That line binds the module level name MyException
in the fn3
file to
the same things to which is it bound in the fnEXP
file. And that is
how the name MyException
becomes usable in the fn3
file.
When you run it:
try:
from fn4 import fn4
fn4(.......)
except MyException as e:
logging.error('MyException executing...')
logging.error(e)
With your code, this line will raise the NameError
you see because you
never imported the name MyException
itself. If you change fnEXP
to
define MyException
as a top level name and then import that name to
the fn3
file, then the name MyException
will be known and the
try
/except
will work.
Cheers,
Cameron Simpson cs@cskk.id.au