Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The bulk of my programming experience has been with C++ and (shudder) FORTRAN (I'm a scientist not a programmer as such, but I do my best). I've recently started using python extensively and find it great. However, I just spent a frustrating few hours tracking down a bug that turned out to be caused by me creating a new object member in a function, i.e.

def some_func(self):
    self.some_info = list()

but, I had already created elsewhere the member some_info for this object for a different purpose, so bad things obviously happened later on, but it was tricky to track back to here.

Now obviously in a language like C++ this is impossible to do, since you can't just create object members on the fly. Because I'm used to the language taking care of this, I don't have a well developed procedural discipline to prevent me abusing the freedom that python (and other dynamically typed languages) provides.

So what is the best way to prevent this kind of mistake when using languages like python?

share|improve this question
2  
You seem to be using “modern” to refer to “dynamic” (wrt typing and binding). There are modern languages which afford expressive freedom without also introducing a propensity for bugs. –  Jon Purdy Sep 5 '13 at 4:25
    
Good point, I've updated the text accordingly. –  Bogdanovist Sep 5 '13 at 5:25
    
Why did you put self.some_info = list() in the first place? You should know that python doesn't have static typing hence it ought to be obvious when you wrote the method that the first line of it would override whatever was in self.some_info before. –  Bakuriu Sep 5 '13 at 7:01

4 Answers 4

This may be a somewhat trivial advice, but try not to create attributes outside of __init__ method (especially not outside the class's methods), unless you really need to. pylint catches this, among many other things.

Of course, there is still a possibility of reassigning an existing attribute to something else entirely, but at least you will have a single place where you can see all the attributes at once. Also this will ensure that right after the construction your object is valid and does not require calls to any other internal state-changing methods.

share|improve this answer

In a nutshell, you make your classes smaller, small enough that such conflicts are easy to spot. Usually when you can't find a way to create a member in __init__ that's a good sign you might want to split it into its own class. Also, avoid using a member when a local variable will do.

When a programming language doesn't impose practices, you have to impose them yourself.

share|improve this answer

I had already created elsewhere the member some_info for this object for a different purpose

Well, you did not post the real names of your class and members, but such things can happen more easily when some_info has an ambigous name, not making clear it's real purpose. So besides the other good answers here, try to avoid that, choose names which document the purpose of a variable more clearly, especially for member variables.

share|improve this answer

You can't. If this is a problem you encounter on a regular enough basis, Python (and probably other dynamically typed languages are a bad choice for you.

share|improve this answer
    
I don't think it's a bad choice for the person, it's breaking old habits accrued from developing in other environments. –  Greg Bair Sep 11 '13 at 19:45
    
I also think that python is great for non-programmers. It's a free MatLab on rocket fuel! –  Vorac Sep 12 '13 at 10:18
    
I stand by my answer: when you make a mistake with a tool often enough that it's worth creating a question like this, the tool is wrong for you. Not wrong, just wrong for you. –  Ross Patterson Sep 12 '13 at 23:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.