0

I wish to make a relatively fleeting object in Python. In Javascript, which has a similar internal semantic for object management (a lookup table) you can do the following:

/* Hopefully I'm not so out of practice with JS that this would cause an error: */
var not_a_defined_class;
not_a_defined_class.this_property_exists_as_of_this_line = 1

In Python, you cannot. The equivalent would be something like the following:

not_a_defined_class = object()
not_a_defined_class.__dict__['this_property_exists_as_of_this_line'] = 1

Evidently, dot-notation to access a member of a class is syntactic sugar:

class DefinedClass(object):
    __init(self):
        self.predefined_property = 2

defined_object = DefinedClass()
defined_object.predefined_property = 5
# Is syntactic sugar for:
defined_object.__dict__['predefined_property'] = 5
# But is read-only
defined_object.undefined_property = 6 # AttributeError

My questions then are as follows:

  1. Is there a difference between .__dict__['predefined_property'] = 5 and .predefined_property = 5?
  2. Is dot-notation read-only outside class definitions (i.e. other than self.new_property =)? (As far as I can tell this is the case)
  3. If so, why? Type safety?
  4. Is there a way I can work around this? Is there a method called by dot-notation that I can recklessly override in my own class, say MessyObject?

Of course, I could use a dictionary object to similar effect. I'm really asking this question to learn more.

1 Answer 1

3

The reason you get an error is that object is a Python class defined in C. Those can't be extended. The same is true for other internal / C-based classes like str and list:

 > a = 'x'
 > a.foo = 1
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 AttributeError: 'str' object has no attribute 'foo'

But you can extend those classes:

>>> class MyString(str): pass
... 
>>> a = MyString()
>>> a.foo = 1
>>> len(a)
0

Re #1: For classes defined in Python code: Usually not. There are some corner cases which is why you should use setattr() instead.

Re #2 and #3: No. As I said above, this is only true for internal types.

Re #4: See above.

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

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.