0

I wonder if it possible to use eval to creates class data attributes. Something like following code:

class Test:
    def __init(self):
        matrix_names = ['F', 'B', 'H', 'Q', 'R', 'x', 'P']
        for matrix in matrix_names:
            print matrix
            operation = "self.%s = self.__matrix_read(%s)" %\
             (matrix, matrix)
            eval(operation)

    def __matrix_read(self, filename):
        return (read(".matrix/%s.csv"%filename))

In iPython I get:

File "<string>", line 1
   self.F = self.__matrix_read(F)
       ^
SyntaxError: invalid syntax
Wawrzek
  • 452
  • 5
  • 18

2 Answers2

7

You can use setattr build in function:

class Test:
    def __init(self):
        matrix_names = ['F', 'B', 'H', 'Q', 'R', 'x', 'P']
        for matrix in matrix_names:
            print matrix
            setattr(self, matrix, self.__matrix_read(matrix))
PasteBT
  • 2,128
  • 16
  • 17
3

Do not use eval for this. Other, better ways already exist if you wish to define attributes at runtime.

If you want the attributes defined and built at instantiation, use setattr() as is recommended in @PasteBT's answer.

If you want the answers to be dynamically expandable, use __getattr__() (good answer clarifying its behavior here).

For example:

class Test:
    def __init__(self):
        self.matrix_names = ['F', 'B', 'H', 'Q', 'R', 'x', 'P']

    def __matrix_read(self, name):
        return (read(".matrix/%s.csv"%filename))

    def __getattr__(self, name):
        if name in self.matrix_names:
            return self.__matrix_read(name)

Or, another way (IMHO cleaner, but YMMV):

class Test:
    # note that this is only called if the attr does not exist
    def __getattr__(self, name):
        try:
            with open(".matrix/{0}.csv".format(name)) as f:
                return f.read()
        except IOError:
            raise AttributeError("{0} does not exist".format(name))

(in python 3 replace IOError with FileNotFoundError). This way, you are not bound to a pre-built list of files, which may or may not be desirable depending on your application.

Community
  • 1
  • 1
J David Smith
  • 4,780
  • 1
  • 19
  • 24