Prev: Why doesn't python's list append() method return the list itself?
Next: Getting started with python on macintosh snow leopard with mysql - need help
From: Grant Edwards on 12 Jul 2010 10:40 On 2010-07-11, Thomas Jollans <thomas(a)jollans.com> wrote: > On 07/11/2010 08:45 PM, wheres pythonmonks wrote: >> On #3: Sorry this is confusing, but I was browsing some struct array >> code from numpy, in which one of the columns contained strings, but >> the type information, supplied in numpy.array's dtype argument, >> specified the type as a an "object" not a string. A string is an object. >> Just wondering why one would do that. > > No expert on numpy, but maybe storing object references is cheaper than > storing strings here ? Strings are objects. IIRC, numpy has special homogeneous array types to hold certain scalar values: byte, int, float, complex. Those special array types allow for very efficient storage and operations. If you want an array of any other type, or a heterogeneous array, then you use an array of objects and then you can put anything into the array (including strings). -- Grant Edwards grant.b.edwards Yow! The PINK SOCKS were at ORIGINALLY from 1952!! gmail.com But they went to MARS around 1953!!
From: sturlamolden on 12 Jul 2010 10:59 On 12 Jul, 07:51, "Alf P. Steinbach /Usenet" <alf.p.steinbach +use...(a)gmail.com> wrote: > We're talking about defining a 'swap' routine that works on variables. I did not miss the point. One cannot make a swap function that rebinds its arguments in the calling stack frame. But a swap function can swap values, given that the type is not immutable: def swap(a,b): a[0],b[0] = b[0],a[0] >>> a,b = [1],[2] >>> swap(a,b) >>> print a,b [2] [1]
From: Alf P. Steinbach /Usenet on 12 Jul 2010 14:11 * sturlamolden, on 12.07.2010 16:59: > On 12 Jul, 07:51, "Alf P. Steinbach /Usenet"<alf.p.steinbach > +use...(a)gmail.com> wrote: > >> We're talking about defining a 'swap' routine that works on variables. > > I did not miss the point. One cannot make a swap function that rebinds > its arguments in the calling stack frame. But a swap function can swap > values, given that the type is not immutable: > > def swap(a,b): > a[0],b[0] = b[0],a[0] > >>>> a,b = [1],[2] >>>> swap(a,b) >>>> print a,b > [2] [1] OK, that's missing the point. I thought you were joking. Cheers & hth., - Alf -- blog at <url: http://alfps.wordpress.com>
From: Alf P. Steinbach /Usenet on 12 Jul 2010 14:28 * Steven D'Aprano, on 12.07.2010 04:39: > On Mon, 12 Jul 2010 03:12:10 +0200, Alf P. Steinbach /Usenet wrote: > >> * MRAB, on 12.07.2010 00:37: > [...] >>> In Java a variable is declared and exists even before the first >>> assignment to it. In Python a 'variable' isn't declared and won't exist >>> until the first 'assignment' to it. >> >> That is a misconception. >> >> In Python a variable is declared by having an assignment to it, which >> for a local variable may be anywhere within a routine. > > Oh, I'm going to regret being sucked into this... > > In *CPython*, but not necessarily other implementations, variables which > are local to a function are not kept in a dictionary-based namespace, but > in slots in the code object (not to be confused with __slots__ used for > classes). Python has STORE_FAST and LOAD_FAST byte-codes for accessing > locals. > > This is intended as a speed, and possibly memory, optimization. I don't > believe this is a requirement though, so implementations may not do this. > > It is true that the slot is created at compile time, and in *that sense*, > local variables exist before they are bound. I'm not entirely convinced > that this is the only sense that matters, but never mind. The error > message given exposes this to the user: > >>>> def f(): > ... print x > ... x = 1 > ... >>>> f() > Traceback (most recent call last): > File "<stdin>", line 1, in<module> > File "<stdin>", line 2, in f > UnboundLocalError: local variable 'x' referenced before assignment > > > If you try this with a global, you get this: > >>>> def f(): > ... global x > ... print x > ... >>>> f() > Traceback (most recent call last): > File "<stdin>", line 1, in<module> > File "<stdin>", line 3, in f > NameError: global name 'x' is not defined > > In this case, there's no doubt that global variable "x" doesn't exist at > all -- there is no key "x" in the global namespace. Yes. What I disproved was the statement that every Python variable is created by the execution of an assignment. Some (the global ones) are. :-) > It seems to me that "a slot to hold the variable is created for local > variables" is an implementation detail, not a language feature. Yes. However, any Python implementation has to implement the same user level semantics in some way (note: use level semantics do not include "space reserved" for an unassigned variable, or even for all assigned variables since with single assignment a sufficiently smart compiler can optimize away the space, but user level semantics do include existence and resultant effect). As I see it it doesn't matter whether the implementation is CPython call frame slots or that mechanism called something else or a different mechanism called the same or a different mechanism called something different; what IMO matters is same semantics, that any assignment to a variable within a routine serves as a compile time declaration, creating that local variable in advance, unless, with Python 3.x., that name has been declared as a 'global' or 'nonlocal'. So, this is a possible point of disagreement. I say the semantics of local variable creation are part of the language definition, but I get the /impression/ that maybe you think it's CPython-specific, that e.g. def foo(): x x = 0 might not raise an unassigned variable exception with some conforming Python implementation, i.e. different effect for same code with different implementations, that this is at least /unspecified behavior/ in Python? > CPython > could easily hide the difference by changing the exception from > UnboundLocalError to: > > NameError: local name 'x' does not exist > > and nobody would be any wiser. (Well, perhaps people who catch > UnboundLocalError, but why would you do that?) > > I also note that UnboundLocalError is a subclass of NameError, so > "variable exists but is not bound" is considered to be a special case of > "variable doesn't exist" rather than a completely independent case. In > that sense, I think I'm on solid ground to say that in Python variables > don't exist until they are bound to a value, and leave it to pedants like > you and I to mention that for CPython local variables have space reserved > for them by the compiler before they are bound. He he. I wouldn't say "space reserved". That is an implementation detail. Cheers, - Alf -- blog at <url: http://alfps.wordpress.com>
From: Rhodri James on 12 Jul 2010 16:19
On Mon, 12 Jul 2010 13:56:38 +0100, bart.c <bartc(a)freeuk.com> wrote: > "Steven D'Aprano" <steve(a)REMOVE-THIS-cybersource.com.au> wrote in > message news:4c3aedd5$0$28647$c3e8da3(a)news.astraweb.com... >> On Mon, 12 Jul 2010 09:48:04 +0100, bart.c wrote: >> >>> That's interesting. So in Python, you can't tell what local variables a >>> function has just by looking at it's code: > >>> def foo(day): >>> if day=="Tuesday": >>> x=0 >>> print ("Locals:",locals()) >>> >>> #foo("Monday") >>> >>> Does foo() have 1 or 2 locals? >> >> That's easy for CPython: it prepares two slots for variables, but only >> creates one: >> >>>>> foo("Monday") >> ('Locals:', {'day': 'Monday'}) >>>>> foo.func_code.co_varnames >> ('day', 'x') >>>>> foo.func_code.co_nlocals >> 2 >> >> So, the question is, is x a local variable or not? It's not in locals, >> but the function clearly knows that it could be. > > So Alf P.S. could be right; x exists, but Python pretends it doesn't > until it's assigned to. CPython, not Python. And as Steven said, x *doesn't* exist. Allowance is made by that specific implementation of the interpreter because x *might* exist, but in this particular case it doesn't and a more dynamic implementation might choose not to reserve a slot just in case. x is created until it's actually used. -- Rhodri James *-* Wildebeeste Herder to the Masses |