Nips
Nips

Reputation: 13890

How to load only one class from module?

I have code:

mod_file = 'mymod.py'
mod_path = os.path.join('.', mod_file)
mod_py = 'mymod'
mod = imp.load_source(mod_py, mod_path)
if hasattr(mod, 'MyClass'):
    instance = py_mod.MyClass()

mymod.py:

class MyClass():

    def __init__(self):
        print 'Hello'
    [...]

print 'something'
a = MyClass()

But "imp.load_source" execute all instructions from this file. I want only get class MyClass - and other thigns skip. How to do it?

Edit:

I can not interfere in the "mymod.py" file, and I do not know how the file will be named, this is example.

I know that in the file will be class 'MyClass'. Other things are undesirable.

Upvotes: 1

Views: 395

Answers (6)

Mark Streatfield
Mark Streatfield

Reputation: 3209

You could wrap the end lines in mymod.py like so:

if __name__ == "__main__":
    print 'something'
    a = MyClass()

The result will be these lines are only executed when mymod.py is executed as a script, not imported as a module.See executing modules as scripts in the Python documentation.

Note however, that if you have other classes defined in mymod.py they will still be imported by imp.load_source.

Edit: as you are unable to modify mymod.py the solution becomes more complicated. You can use the ast module to parse the code:

import ast
with open("mymod.py", "r") as fd:
    module_ast = ast.parse("".join(fd.readlines()))

You would then traverse the ast (module_ast) and isolate the MyClass tree node. This link gives an example of modifying python code inline, and this shows how to analyse code. You could use a combination of techniques from those links to isolate ast nodes related to MyClass and delete the rest. But this would end up making a number of assumptions about what mymod.py actually contains.

Upvotes: 3

Sven Marnach
Sven Marnach

Reputation: 602755

  1. Don't write your own plug-in system. There are too many of them already.
  2. While it is theoretically possible to inspect the AST of a module to only extract only the bits you need, this will in practice lead to all kind of weird corner cases, and it is a Bad Idea. Don't do it. Require plug-ins to be written in a way that they can be imported without side effects.

Upvotes: 0

barak manos
barak manos

Reputation: 30166

Step #1 - create file main.py with the following code:

from MyFolder import MyClass
instance = MyClass()
# Do whatever you wanna do with the MyClass instance...

Step #2 - create folder MyFolder next to file main.py.

Step #3 - rename file mymod.py to __init__.py, and put it inside folder MyFolder.

Upvotes: 0

Thomas Orozco
Thomas Orozco

Reputation: 55303

This is not possible in Python. You should design your code so that it has no side-effects when it's imported.

Also, note that modules are only executed once, regardless of how many times you use import module on them, so it's a very bad idea to rely on side effects at module import.

Nonetheless, if what you need is to have your module behave differently when it's imported than when it's run, then you can achieve that goal by using:

# module.py
# Code that will always run
...

if __name__ == "__main__":
    # Code that will only run if you do python module.py
    # Usually print statements, argument parsing... 
    ...

In your case, you would do:

    class MyClass():

    def __init__(self):
        print 'Hello'
    [...]

if __name__ == "__main__":
    print 'something'
    a = MyClass()

An usual way of using this is by doing:

def main():
     # do stuff

if __name__ == "__main__":
    main()

Upvotes: 3

binaryatrocity
binaryatrocity

Reputation: 976

I believe the most pythonic solution here would be to just import the class from your other Python file. To do this, replace your imp.load_source() with:

 from mymod import MyClass

Upvotes: 0

Raydel Miranda
Raydel Miranda

Reputation: 14370

class MyClass():

    def __init__(self):
        print 'Hello'
    [...]

if __name__ == '__main__':
    print 'something'
    a = MyClass()

All statements in the if __name__ block get executed only if that module is executed directly and not when the module is imported.

Upvotes: 1

Related Questions