Earlier quoted context omitted.
x isn't a variable, it's a tag. Because Python is dynamically typed, x can be an int one minute and a function the next, so every attribute on a class is stored as a pointer to an object, including attributes that are integers (which is an object) and functions (which are also objects). Because you aren't declaring the type of x (Python doesn't allow that), Python has to treat x = 1 the same way it'd treat def x(self…
Where x is an identifier (presumably aka tag?) that refers to a variable, it is not beyond the bounds of possibility for "x = 1" to be interpreted as "store the value of 1 into the variable that is referred to by identifier x". Plenty of languages, including dynamically typed ones, manage to do this, as indeed Python does in many cases. Not knowing the type of x is unrelated to question of where x's value is stored,…
Common Python Mistakes
131–140 of 146 posts
Re: Common Python Mistakes
#132Earlier quoted context omitted.
Where x is an identifier (presumably aka tag?) that refers to a variable, it is not beyond the bounds of possibility for "x = 1" to be interpreted as "store the value of 1 into the variable that is referred to by identifier x". Plenty of languages, including dynamically typed ones, manage to do this, as indeed Python does in many cases. Not knowing the type of x is unrelated to question of where x's value is stored,…
I'm not really sure I understand your point. The value of x is still going to be in memory, but you may not have any references to it and it will be garbage collected. The disconnect is in thinking x is a variable and not an identifier. x points to the object in the parent until it is overridden. This allows me to dynamically alter the functionality of a class and all it's subclasses that don't override that function…
(edit: replaced "an expression" with "a statement")
Re: Common Python Mistakes
#133OT but this page hard crashes Safari on iPhone.
Also crashes Safari on my OS 10.5 Mac, and is unusably laggy in Firefox on the same computer. All sorts of thrashy javascript nonsense seems to be going on.
Mildly excessive? /s
Re: Common Python Mistakes
#134This is a pretty good list of gotchas, but it's important when writing something targeted at beginners to be as precise and clear as possible. Nearly every section here either uses terminology poorly, is slightly incorrect, or has difficult examples. Python supports optional function arguments and allows default values to be specified for any optional argument. No, specifying a default is what causes an argument to b…
Just to notice: this text is not targeted at beginners, in my opinion. These are upper-intermediate to advanced level gotchas.
3 is a really easy mistake to make for anyone (which is why the syntax was changed).
6, 7, 9 and 10 are more obscure, and where I really appreciate this article -- and they definitely can be issues for more experienced Python devs.
Re: Common Python Mistakes
#135Earlier quoted context omitted.
I'm not really sure I understand your point. The value of x is still going to be in memory, but you may not have any references to it and it will be garbage collected. The disconnect is in thinking x is a variable and not an identifier. x points to the object in the parent until it is overridden. This allows me to dynamically alter the functionality of a class and all it's subclasses that don't override that function…
I'm not disputing how or why it works, just saying that I think it is poor design, as it causes a statement that looks like variable assignment to actually produce overriding. I think this violates the principle of least astonishment, and I suspect there is no good reason (beyond implementation simplicity) why Python class variables do behave this way. (edit: replaced "an expression" with "a statement")
Re: Common Python Mistakes
#136Slightly off topic, but does anyone know of a resource that has 'most common mistakes' for different languages all in one place? It's certainly possible to google for blog posts and stack overflow questions to assemble such a list, but it would be handy to have them all in one place. My use case is when interviewing candidates I often ask them to rate themselves on a scale of 1-5 in the languages they know, and then…
These would be interesting research areas for instrumenting IDEs / other eco-system tools to collect some of this data. (I'm sure there is already some work in some of these areas and would appreciate names or links to high-quality reviews.)
Re: Common Python Mistakes
#137In "Common Mistake #2", I'd say that the mistake is fairly obvious to anyone who understands even a little bit about OOP and inheritance. Since class C doesn't define its own variable x, it has to be that it inherits the x in class A, so there's no reason to be surprised that C.x changes when A.x does.
While I agree that the "problem" case can be seen as obvious when considered in isolation, really it's the behaviour of the two cases taken together that can seem inconsistent. Nothing about understanding OOP or inheritance will prepare a person for that.
Edit: Added some extra blank lines because lines were getting joined together.
# class_variables.py
class A(object):
x = 1
class B(A): pass
class C(A): pass
print "Initially, A.x, B.x, C.x and their ids:"print A.x, B.x, C.x
print id(A.x), id(B.x), id(C.x)
B.x = 2
print "After B.x = 2, A.x, B.x, C.x and their ids:"
print A.x, B.x, C.x
print id(A.x), id(B.x), id(C.x)
A.x = 3
print "After A.x = 3, A.x, B.x, C.x and their ids:"
print A.x, B.x, C.x
print id(A.x), id(B.x), id(C.x)
And the output:
>python class_variables.py
Initially: A.x, B.x, C.x and their ids:
1 1 1
30519808 30519808 30519808
After B.x = 2: A.x, B.x, C.x and their ids:
1 2 1
30519808 30519796 30519808
After A.x = 3: A.x, B.x, C.x and their ids:
3 2 3
30519784 30519796 30519784
Re: Common Python Mistakes
#138Re: Common Python Mistakes
#139Earlier quoted context omitted.
Still hugely useful when you want to write long string constants. Imho, adding a comma after each list element is a good practice. You can easily swap them, add more, and never run into a an issue you describe: foo = [ "a", "bc", "def", # comma here, too ]
You could easily use a + operator then. I find the behavior surprising. I would expect a syntax error. You get a syntax error if you write two integers next to each other (separated by a space) or two of any other thing but somehow "a" "b" got converted to "ab". If I've discovered it myself I would be tempted to fill a bug report. It goes against Python mantra: "Explicit is better than implicit" It seems someone thou…