1

I'm trying to make an engine that takes the contents of a file that has python files and functions within them in a format as follows:

lib1 func1 func2 func3
lib2 func4

etc. I set up a test with two python files and three functions, but the code I am using to import the libraries and functions isn't working:

class engine (object):
    def __init__ (self, sceneFile):
        # gets contents of sceneFile, then closes
        scenes         = open (sceneFile, 'r')
        lines = scenes.readlines ()
        scenes.close ()
        self.libs = []

        # finds functions and libraries
        for i in range (len (lines)):
            lineContents = lines[i].split()
            self.libs.append (importlib.import_module (lineContents[0]))  # libraries in sceneFile
            for j in range (len (lineContents) - 1):
                self.libs[i].append (lineContents[j + 1])          # functions in sceneFile

    def start (self, nextScene):
        # finds function and library, imports
        for i in range (len (self.libs)):
            for j in range (len (self.libs[i])):
                if self.libs[i][j] == nextScene:
                    nextScene = getattr (self.libs[i], self.libs[i][j])
                    self.start (nextScene)

When I try running this with the test programs, this error pops up:

Traceback (most recent call last):
  File "ugsE.py", line 32, in <module>
    Engine = engine ("ugsEtest.txt")
  File "ugsE.py", line 21, in __init__
    self.libs[i].append (lineContents[j + 1])          # functions in sceneFile
AttributeError: 'module' object has no attribute 'append'

What does this mean? I have a feeling that it's because I'm creating a list of modules, but shouldn't that work?

2
  • 2
    Whatever is at self.libs[i] is not a list so it has no append() method. Commented Jun 12, 2015 at 13:56
  • It's not clear what you are trying to achieve: what is the final 'self.libs' list you want to get? At the moment you are appending module objects to the list, then you are "appending" strings with function names to the module which doesn't work of course Commented Jun 12, 2015 at 13:59

2 Answers 2

5

libs is a list of modules, so libs[i] is a module. libs[i].append fails because you can't append something to a module.

Strictly, this code will actually run in the unlikely case that libs[i] is a module that exposes its own append method (with a compatible signature), but this certainly won't do what you want.


You could achieve what you want by turning libs into a list of tuples, where the first element is the library and the second is a list of functions associated with that library:

for line in lines:
    lineContents = line.split()
    self.libs.append((importlib.import_module(lineContents[0]), lineContents[1:]))

Then you can access library i as self.libs[i][0] and function j as self.libs[i][1][j].

If you want, you can also eliminate the loop and reduce the whole of __init__ to just three lines using slices, list comprehensions, and a with statement:

with open(sceneFile, 'r') as scenes:
    lines = (l.split() for l in scenes)
    self.libs = [(importlib.import_module(l[0]), l[1:]) for l in lines]
Sign up to request clarification or add additional context in comments.

1 Comment

First of all, thank you very much! I have never used tuples before, and thus I am having trouble with the second part of the code (the start function). I have made an edit which doesn't print errors, but doesn't appear to run the functions.
0

libs looks like an element of the array. Unless you can guarantee self.libs[i] is itself an attay it won't have an append method.

If you want to 'append' at an index, use insert(i, x)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.