8

I am quite new to Python and I cant seem to be able to understand this.Consider this simple Python code.

class point:
   i = 34


test = point()
test.y = 45

print test.y 

As you can see I instance of point called test but then did test.y = 45 when y is not a data member of the point class. No error was thrown and the y attribute seems to have been added to the class automatically.

Why did this happen? Isn't this a misfeature? Or am I missing something very basic. The same thing cannot be done with C++ and it would throw a compiler error. Any reason for this strange feature?

smilingbuddha
  • 14,334
  • 33
  • 112
  • 189
  • 1
    I didn't cast the downvote, but your question shows that you have very little knowledge of Python. You should go through the Python [tutorial](http://docs.python.org/tutorial/). – Yunchi Jul 21 '12 at 21:37
  • I didn't downvote but: you've just said that *anything that can't be done with C++ is a misfeature*. Learn a few more languages. – Hamish Jul 21 '12 at 21:45
  • 1
    @Hamish I never said "anything that can't be done with C++ is a misfeature" I am coming from a C++ / C background and hence I mentioned the C++. My question on this being a misfeature, was NOT meant to be rhetorical, it was genuine. Surely Python veterans can guide me on this point and correct my misconceptions. – smilingbuddha Jul 21 '12 at 21:52
  • I dont think this was worthy of a downvote and for the record I understood your reference to c++ as being purely inquisitive – jdi Jul 21 '12 at 21:57
  • 1
    You can define a class to not allow it as well. – jdi Jul 21 '12 at 22:01
  • @jdi Thank you, that is useful information. – smilingbuddha Jul 22 '12 at 14:05

3 Answers3

7

Because this is Python, not C++ (or Java). Calling it a misfeature is a fundamental misunderstanding of how Python works.

In Python you don't declare variables, or attributes. There's no such thing as "a data member of the point class". Your i is just a class-level variable, but it would be the same wherever you associate that attribute with the class. You can dynamically add attributes to classes, instances, modules, whatever you like. That's what it is to be a dynamically typed language.

In fact, doing this like this is the only way to define instance variables. As I said, your i above is a class attribute, shared by all members of the class. The only way to get an instance-level variable is to "dynamically" add it, usually in the __init__ method but you can do it wherever you like.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • And you can specifically prevent assignments as part of the class def if you wanted. – jdi Jul 21 '12 at 22:00
4

It is just a common thing from scripting languages. Python lets you do it, Ruby also, and in deed, you never had to pre-define your local variables. Why not also in your classes? Not only that, you can choose if the new inserted variables/functions affect only one object or all instances of that class.

People who are doing heavy things in TDD and UnitTesting love that misfeature. Actually I would even go as far as to say that C++ static typing does not reduce my programs bugs nearly as much as a language that ease my unit tests giving me exactly that.

However, if you are concerned, you can always use _____slots_____

https://stackoverflow.com/a/3603624/253098

Community
  • 1
  • 1
SystematicFrank
  • 16,555
  • 7
  • 56
  • 102
2

This is just how Python works. You can create new attributes on classes or instances at will. It has the disadvantage that many errors can't be caught at compile time, but it has the advantage of allowing more flexible dynamic programming.

If you are surprised by this behavior, you should read the Python tutorial to familiarize yourself with Python basics.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384