3

I tried executing this piece of code in my Idle and have the following error,

class Myclass():
    i = 1

x = Myclass()
x.y = 10
x.i=10
x.i
# 10
x.y
# 10

This class has only 1 attribute 'i', but when I assign x.y = 10, how will Python allow it to work. Isn't that a problem? How do I prevent it happening?

8
  • 4
    You come from a Java background, uh? :D Is not a bug... is a feature designer-daily.com/wp-content/uploads/2009/06/bug-feature.jpg Commented Aug 7, 2012 at 16:55
  • 3
    dirtsimple.org/2004/12/python-is-not-java.html Commented Aug 7, 2012 at 16:57
  • I think it's a very interesting question, though, specially, the how to prevent part... out of curiosity, mainly Commented Aug 7, 2012 at 16:57
  • 4
    Python lets consenting adults do that :) ...the only problem with your code is that your class should inherit from object Commented Aug 7, 2012 at 17:01
  • 1
    @delnan... I'm with you here, man... errr... person (you never know)... I've suffered things like... seeing if self.attrib: with attrib not being in init so... good luck trying to track where that attribute came from by reading 4 or 5 files of 4000 lines each... (Sorry for this irrelevant comment but I guess I got kind of traumatized with that and this helps me save a shrink) Commented Aug 7, 2012 at 17:13

3 Answers 3

4

As other answers have mentioned, this is a feature not a bug.

If you want to enforce only a limited set of attributes, you can use __slots__ with new-style classes (classes that inherit from object):

class Myclass(object):
    __slots__ = ['i']

>>> x = Myclass()
>>> x.i = 10
>>> x.y = 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Myclass' object has no attribute 'y'
Sign up to request clarification or add additional context in comments.

3 Comments

Is it a advantage or dis-advantage?
That's not the main intent to __slots__ though (space savings are), and it comes with a whole lot of weird caveats. cf docs.python.org/reference/datamodel.html#slots
@user1050619 - That depends on how you look at it, it makes the language more flexible and allows you to write shorter code, but it can also potentially introduce some subtle bugs. For example misspelling an attribute in compiled languages would probably be a compile-time error, but in Python you might not catch it until run-time.
2

Python, unlike many other languages like Java, assigns class members dynamically. That means that you don't need to include a variable in the class's definition to be able to assign to it.

Also note that there is a difference between a class variable like the one you are assigning:

class Myclass():
     i = 1

and a class member:

class Myclass():
    def __init__(self):
        self.i = 1

2 Comments

Additionally, what you have written there is a class variable (like a static variable in java). Instance variables are defined inside __init__
This is misleading. Assignment at class scope has, in fact, nothing to do with object attributes - it's closer to static members.
0

That is how you define class variables in Python. You could prevent this behaviour using some "magic" functions but that is generally not recommended.

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.