Quantcast

python question

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

python question

Brian May-11
Hello,

The following code:

=== a ===
import b
import c
b.init()
print b.value
c.action()
=== end ===

=== b.py ===
value = None
def init():
    global value
    value = "something"
=== end ===

=== c.py ===
from b import value
import b

def action():
    print value
    print b.value
=== end ===

generates the following output:

=== output ===
something
None
something
=== end ===

Question: Why is the second line None, and not something? Then, why is
the third line something?

This is kind of confusing me.

I suspect it might be some sort of misunderstanding I have with
Python. However I can't think of what that might be. I would have
though "from b import value" and "import b" should give the same
results.

If I swap the order of "import c" and "b.init()" in a, then all the
results are something.

If I change the value in the line "value = None", then I get that
value instead of None on the 2nd line - is like I have two copies of
b.value.

Thanks
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Noon Silk
Brian May asks:

> [...]
>
> Question: Why is the second line None, and not something? Then, why is
> the third line something?
>
> This is kind of confusing me.
>
> I suspect it might be some sort of misunderstanding I have with
> Python. However I can't think of what that might be. I would have
> though "from b import value" and "import b" should give the same
> results.

The "from" style will create local variables for each of the things
you import in that fashion:
http://docs.python.org/reference/simple_stmts.html#grammar-token-import_stmt

So yeah, you have two copies. I think what you'll notice also is that
swapping the order of b.init and import c works because *at the time
of import* the global "value" in b has the "something" value. I think
it'll be more clear if you note that subsequent changes to b.value and
value will be independent ...

Just consider that at the time of "from .. import ..." you get a copy
of whatever the global value is. In the first case, it's clearly None.
In the second case it's clearly something. This agrees with what you
see.



> If I swap the order of "import c" and "b.init()" in a, then all the
> results are something.
>
> If I change the value in the line "value = None", then I get that
> value instead of None on the 2nd line - is like I have two copies of
> b.value.
>
> Thanks
> --
> Brian May <[hidden email]>

--
Noon Silk

Fancy a quantum lunch? https://sites.google.com/site/quantumlunch/

"Every morning when I wake up, I experience an exquisite joy — the joy
of being this signature."
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Andreux Fort-2
In reply to this post by Brian May-11

short answer: python is "pass by reference to value", meaning you should follow Google's style guide and only import packages or modules, never things inside modules

When you do "from x import y", and then somewhere else update "x.y" (via import x), you're updating two different variable references.

On Apr 3, 2012 12:05 PM, "Brian May" <[hidden email]> wrote:
Hello,

The following code:

=== a ===
import b
import c
b.init()
print b.value
c.action()
=== end ===

=== b.py ===
value = None
def init():
   global value
   value = "something"
=== end ===

=== c.py ===
from b import value
import b

def action():
   print value
   print b.value
=== end ===

generates the following output:

=== output ===
something
None
something
=== end ===

Question: Why is the second line None, and not something? Then, why is
the third line something?

This is kind of confusing me.

I suspect it might be some sort of misunderstanding I have with
Python. However I can't think of what that might be. I would have
though "from b import value" and "import b" should give the same
results.

If I swap the order of "import c" and "b.init()" in a, then all the
results are something.

If I change the value in the line "value = None", then I get that
value instead of None on the 2nd line - is like I have two copies of
b.value.

Thanks
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug

_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Brian May-11
In reply to this post by Noon Silk
On 3 April 2012 12:24, Noon Silk <[hidden email]> wrote:
> The "from" style will create local variables for each of the things
> you import in that fashion:
> http://docs.python.org/reference/simple_stmts.html#grammar-token-import_stmt

Interesting. Particularly as I copied this code from Django. Hmmm....
It works in Django, but only because the values don't change - not
sure this is a good assumption. Really.

Will have to be more careful about this in the future I think.

Thanks for the responses.
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Andreux Fort-2

Yup, Django's style should not be emulated, to say the least.

The whole django.conf.settings module magic should be a good warning :)

If an import begins "from", it is either lazy or dangerous, potentially both :/

On Apr 3, 2012 12:33 PM, "Brian May" <[hidden email]> wrote:
On 3 April 2012 12:24, Noon Silk <[hidden email]> wrote:
> The "from" style will create local variables for each of the things
> you import in that fashion:
> http://docs.python.org/reference/simple_stmts.html#grammar-token-import_stmt

Interesting. Particularly as I copied this code from Django. Hmmm....
It works in Django, but only because the values don't change - not
sure this is a good assumption. Really.

Will have to be more careful about this in the future I think.

Thanks for the responses.
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug

_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

William Leslie-2
In reply to this post by Andreux Fort-2
On 3 April 2012 12:25, Andreux Fort <[hidden email]> wrote:
> short answer: python is "pass by reference to value", meaning you should
> follow Google's style guide and only import packages or modules, never
> things inside modules

Alternatively, don't rebind global names.  I can count the number of
times I've seen the global statement used in real code on the hand of
a yakuza.  If your module definitions are declarative, this should
never be an issue.

--
William Leslie
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Andreux Fort-2

Agreed. The global keyword is never be needed in readable code. (Modules are singletons, after all)

On Apr 3, 2012 1:37 PM, "William ML Leslie" <[hidden email]> wrote:
On 3 April 2012 12:25, Andreux Fort <[hidden email]> wrote:
> short answer: python is "pass by reference to value", meaning you should
> follow Google's style guide and only import packages or modules, never
> things inside modules

Alternatively, don't rebind global names.  I can count the number of
times I've seen the global statement used in real code on the hand of
a yakuza.  If your module definitions are declarative, this should
never be an issue.

--
William Leslie
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug

_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Brian May-11
On 3 April 2012 13:41, Andreux Fort <[hidden email]> wrote:
> Agreed. The global keyword is never be needed in readable code. (Modules are
> singletons, after all)

In my case, I need my module to work both with Django, using Django
settings - and without Django using settings that are passed to the
module. The variables in question need to be global (I think) so that
the (optional) Django middleware layer can access them.

I have now uploaded the module in question to github -
https://github.com/VPAC/python-tldap - Fakes transaction support for
LDAP, by manually queuing and rolling back LDAP requests as required.
Designed so that Placard - our user management tool won't leave LDAP
database inconsistent with db database if an error occurs (the db
database supports transactions, but the LDAP doesn't). e.g. what
happens is that the operator tries to create a user, which creates an
LDAP entry then an error occurs. The db is rolled back, but the LDAP
entry still exists. The operator repeats the operation, and gets an
LDAP error that the entry already exists.

The optional middleware means that code doesn't have to be modified to
take advantage of this, all HTTP requests turn on transaction support.
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: python question

Anthony Briggs-3
In reply to this post by Brian May-11
Stepping through this in a debugger (eg. Winpdb) might help you follow the chain of cause and effect.

Anthony

On 3 April 2012 12:05, Brian May <[hidden email]> wrote:
Hello,

The following code:

=== a ===
import b
import c
b.init()
print b.value
c.action()
=== end ===

=== b.py ===
value = None
def init():
   global value
   value = "something"
=== end ===

=== c.py ===
from b import value
import b

def action():
   print value
   print b.value
=== end ===

generates the following output:

=== output ===
something
None
something
=== end ===

Question: Why is the second line None, and not something? Then, why is
the third line something?

This is kind of confusing me.

I suspect it might be some sort of misunderstanding I have with
Python. However I can't think of what that might be. I would have
though "from b import value" and "import b" should give the same
results.

If I swap the order of "import c" and "b.init()" in a, then all the
results are something.

If I change the value in the line "value = None", then I get that
value instead of None on the 2nd line - is like I have two copies of
b.value.

Thanks
--
Brian May <[hidden email]>
_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug


_______________________________________________
melbourne-pug mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/melbourne-pug
Loading...