1

In python, instances of classes can have custom attributes set dynamically:

class A(object):
    pass

a=A()
a.x=1

This, however, doesn't work if you instantiate object

object().x=1 
#raises AttributeError: 'object' object has no attribute 'x'

object has no __dict__ attribute to store the custom attributes, so this doesn't work.

What's the easiest way to create a object where we can dynamically create custom attributes?

3
  • 1
    What's wrong with a=A() approach? Commented Dec 4, 2013 at 11:39
  • I don't get your problem. What exactly do you need? Your method is completely fine as it is. Commented Dec 4, 2013 at 11:39
  • @aIKid,alko I guess there's no problem with it, I was just curious if there was a easier way. Also, creating a custom class for what will be totally unrelated instances feels "wrong" from a OOP perspective - someone reading the code will think the instances are related when they're not. Commented Dec 4, 2013 at 11:47

3 Answers 3

3

Seems that your example with creating an "empty" class is the fastest solution.

Nevertheless I wouldn't recommend doing this. When you access the attribute 'x' before assignment, you'll get an AttributeError. In other places inside your application you will not be able to determine how to handle objects, because you can't use type-checking to determine the object's features (attributes etc.). You'll always have to use hasattr() etc.

If you still want an object accepting any attribute names, consider overriding __getattr__ and __setattr__ in your class. See this python doc: http://docs.python.org/2/reference/datamodel.html#object.__getattr__

Sign up to request clarification or add additional context in comments.

3 Comments

+1 fair warnings. The reason I want to do this is because I need to mock objects, and I can't instantiate the original class (the original objects are created using C). Overriding __getattr__ would be a bit of overkill, since I just need to make sure two attributes exist, and I create them immediately after creating the mock object
In that case you could use your class A(object): pass approach. Or you create a class creating the attributes you need in its __init__().
1

A trick I've seen is:

x = lambda: magic
x.foo = 1
x.bar = 2

Which takes advantage of the fact functions have a __dict__

1 Comment

Nice! It never occurred to me to use a function
1

The way you propose in your question is generally fine (and often used) for mocking. However, if you'd doing it a lot, you might want to look at the mock library. In Python3, its part of the stdlib (import unittest.mock)

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.