2

I was wondering if the following is possible in python 2.7 or 3.x:

Class A:
    def inject(self, **args):
        ... do something ...

    def print(self):
        print(self.x)

x = np.ones(10)
a = A()
a.inject(x)
a.print()

Note that I want inject to be very general and be able to add any object to the class instance.

What are your thoughts? Is this how I imagined possible?

Edit:

I also would like to inject many variables to the additional injected:

y = np.ones(10)
z = np.ones(10)
a.inject(y, z)
2
  • 2
    Why do you need inject? You can just add an attribute to a class instance, eg a.x = x. Commented Nov 21, 2016 at 12:08
  • I know, but I would also like to use something like a.inject(x, y) Commented Nov 21, 2016 at 12:09

2 Answers 2

2

What you probably need is to use setattr(a, "x", x).

But if you want to use this call in inject(self, name, value) function, then it might be useful to add check which would prevent overwriting an existing attribute - You might want to use if hasattr(self, name): raise AttributeError('attribute already exists') or something like that. Without this check you might be quite surprised someday what is happenning with your objects after you have accidentally overwritten attributes. Just imagine 'accidental' a.inject("inject", x) ;)

But looking at your code, you are trying to use something like 'Python-with-classes' and it looks too 'java-ish'. In Python, you do not need to define inject() and print() in your class. You can simply write:

a = object()
x = 5
setattr(a, "x", x)
print(a.x)  # btw. how does your implementation `a.print()` in the question knows that attribute `x` exists?

I you want to prevent overwriting existing attributes (i.e. allow only the first injections) and still be pythonic, define your class like this:

class A(object):  # note the 'object' here, it is the 'new style' class
    def __setattr__(self, name, value):
        if hasattr(self, name):
            raise AttributeError("attribute '{}' already exists".format(name))
        object.__setattr__(self, name, value)

then you can write this:

a = A()
x = 5
a.x = x
a.x = 10  # raises error
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, I made a wrong comment about adding undefined attributes to an object automatically even without having defined __setattr__(...) in the class which would allow it. I really confused it with JavaScript. Fixed the text... it should be correct now.
1

If I understand your question correctly then you should use setattr:

class A:
    def inject(self, name, value):
        setattr(self, name, value)

    def print(self):
        print(self.x)

x = [1, 1]
a = A()
a.inject('x', x)
a.print()
>> [1, 1]

4 Comments

Indeed this is what I use now. But I thought maybe I can save the redundant step of the naming a.inject('x', x) as the variable x itself already contains the name 'x'
@ArmenAvetisyan No, you can't. The list [1, 1] has no idea whatsoever that there is a reference to it that happens to be called x.
@ArmenAvetisyan: variable don't contain their own names. The objects they are referring to might have names of their own, but variables do not.
@ArmenAvetisyan You may find this article helpful: Facts and myths about Python names and values, which was written by SO veteran Ned Batchelder. Also see, Other languages have "variables", Python has "names".

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.