Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
w_hat
Jul 8, 2003

JoeNotCharles posted:

Nope, should be fine. (Don't actually put the "..." in - I just used that to mark code that I'd cut out.) Are you sure your indentation's correct?

You might have to import pywintypes, but it would give a different error if that was the problem.

From one error to another:
Traceback (most recent call last):
File "C:\Python25\cpumon.py", line 44, in <module>
except pywintypes.error:
NameError: name 'pywintypes' is not defined

I should probably get around to actually learning Python instead of hacking it together.

Adbot
ADBOT LOVES YOU

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

w_hat posted:

From one error to another:
Traceback (most recent call last):
File "C:\Python25\cpumon.py", line 44, in <module>
except pywintypes.error:
NameError: name 'pywintypes' is not defined

I should probably get around to actually learning Python instead of hacking it together.

Interesting you should say this now - Someone just posted an excellent Python reading list here: http://www.wordaligned.org/articles/essential-python-reading-list

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

JoeNotCharles posted:

You might have to import pywintypes, but it would give a different error if that was the problem.

w_hat posted:

From one error to another:
Traceback (most recent call last):
File "C:\Python25\cpumon.py", line 44, in <module>
except pywintypes.error:
NameError: name 'pywintypes' is not defined

Really, what was unclear about that?

cLin
Apr 21, 2003
lat3nt.net
As a person who has learned C++ and PHP, how easy is Python to get into? Pros and cons versus PHP? Figured I'd ask in here since it doesn't really warrant its own thread.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

m0nk3yz posted:

Interesting you should say this now - Someone just posted an excellent Python reading list here: http://www.wordaligned.org/articles/essential-python-reading-list

Ohh and here I thought I was the only one that had this reaction when browsing the library docs:

bitprophet
Jul 22, 2004
Taco Defender

cLin posted:

As a person who has learned C++ and PHP, how easy is Python to get into? Pros and cons versus PHP? Figured I'd ask in here since it doesn't really warrant its own thread.

It's very easy to get into, and is generally better than PHP in every way save for not being ubiquitous on shared Web hosting environments like PHP is. I say this as someone who's been paid to write both PHP and Python and is currently paid to do...both :psyduck:

My background pre-Python was Java, VB and PHP and I absolutely fell in love with Python for various reasons. Largely it's just very close to my idea of an ideal language - the syntax is incredible, being both clean and very powerful/concise; the library support is great; the philosophy behind it is well thought out for the most part; the community is full of experienced, intelligent and pragmatic coders from every programming background you could imagine; I could go on.

Comparing to PHP, one of its largest strengths is that it's generally very consistent and clean, where PHP is one huge ugly namespace with inconsistent function names and/or argument specifications.

In addition, PHP's type system is such that it's extremely easy to make mistakes that are difficult to debug (e.g. the implicit cast of a string to an int during some math on line 10 is causing tax to not be applied on line 257, but without any error messages of any sort cropping up) and more explicit languages like Python avoid that almost entirely.

w_hat
Jul 8, 2003

JoeNotCharles posted:

Really, what was unclear about that?

Christ, I totally missed that, thanks.

cLin
Apr 21, 2003
lat3nt.net

bitprophet posted:

It's very easy to get into, and is generally better than PHP in every way save for not being ubiquitous on shared Web hosting environments like PHP is. I say this as someone who's been paid to write both PHP and Python and is currently paid to do...both :psyduck:

My background pre-Python was Java, VB and PHP and I absolutely fell in love with Python for various reasons. Largely it's just very close to my idea of an ideal language - the syntax is incredible, being both clean and very powerful/concise; the library support is great; the philosophy behind it is well thought out for the most part; the community is full of experienced, intelligent and pragmatic coders from every programming background you could imagine; I could go on.

Comparing to PHP, one of its largest strengths is that it's generally very consistent and clean, where PHP is one huge ugly namespace with inconsistent function names and/or argument specifications.

In addition, PHP's type system is such that it's extremely easy to make mistakes that are difficult to debug (e.g. the implicit cast of a string to an int during some math on line 10 is causing tax to not be applied on line 257, but without any error messages of any sort cropping up) and more explicit languages like Python avoid that almost entirely.

Wow, sounds like something I'd like to learn. What books do you python developers recommend? Something with examples since I learn best with it. How does a program work anyways? I know for PHP you can just write the code into the php file and execute it (printing hello world in index.php and going to index.php), but I never seen any websites with anything that'll indicate it runs off python code.

edit: oh yea, main reason I am interested in it cause I noticed for sites like codegolf.com where programmers from many languages compete for shortest code, python is usually way shorter than php with perl leading as the smallest amount of coding.

cLin fucked around with this message at 23:48 on Feb 2, 2008

bitprophet
Jul 22, 2004
Taco Defender

cLin posted:

Wow, sounds like something I'd like to learn. What books do you python developers recommend? Something with examples since I learn best with it. How does a program work anyways? I know for PHP you can just write the code into the php file and execute it (printing hello world in index.php and going to index.php), but I never seen any websites with anything that'll indicate it runs off python code.

edit: oh yea, main reason I am interested in it cause I noticed for sites like codegolf.com where programmers from many languages compete for shortest code, python is usually way shorter than php with perl leading as the smallest amount of coding.

Python has no explicit compilation step like C++, it's interpreted, meaning it's closer to Perl or shell scripting - you typically either write a source file and tell the interpreter to run it, or you just enter the interpreter yourself and execute code in there. It can also be run in a Web server environment like PHP typically is, but most people do that via a Web framework (Django, TurboGears, Pylons, etc) as opposed to random scripts running at e.g. https://www.mysite.com/myscript.py.

That's why you never see sites looking like they run on Python - the frameworks mentioned tend to favor clean URLs (e.g. https://www.mysite.com/section/subsection/location/) and not URLs that look like filenames :) (In such a situation, there isn't technically one script getting called at that URL - it goes to a URL dispatch function which decides what code to execute/what template to render/etc)

CodeGolf is kind of silly but does serve as a metric for how concise/powerful a language is. Python generally gets high marks in that department due to a combination of factors. For example, list comprehensions make iterative tasks really easy/simple, like here where I have a list of dicts (associative arrays in PHP) with peoples' names and ages and I want a list of just the ages:

code:
people = [{'name': 'Bob', 'age': 15}, {'name': 'Susy', 'age': 32}, 
    {'name': Henry', 'age': 26}]
ages = [x['age'] for x in people]
Compare to the equivalent PHP:

code:
$people = array(array('name' => 'Bob, 'age' => 15), 
    array('name' => 'Susy','age' => 32), 
    array('name' => 'Henry', 'age' => 26)
);
$ages = array();
foreach($people as $person) {
    $ages[] = $person['age'];
}
Another notable feature of Python's syntax is that everything is expression-based, like building blocks in a way, so things can be easily composed. Imagine a function called getPeople that returns the 'people' list/array from the previous example; and imagine wanting to call that function and do something with its return value. In PHP you have to break this up into at least two statements:

code:
$retval = getPeople($arg1,$arg2);
$first_person = $retval[0];
In Python you just make one statement:

code:
first_person = getPeople(arg1,arg2)[0]
This becomes even more useful when (not if; this comes up a lot!) you need to grab stuff that's nested pretty deep. Imagine our 'people' above are actually objects instead of dicts, and we want to call a person's, say, 'listOfFriends()' method - which returns more People - and grab the first friend's age. My PHP object syntax is hazy (been working with very non-OO PHP), but I think it would look like this:

code:
$retval = getPeople($arg1,$arg2);
$first_person = $retval[0];
$firsts_friends = $first_person->listOfFriends();
$ffa = $firsts_friends[0]['age'];
Python? Still one line, and still very readable and obvious.

code:
ffa = getPeople(arg1,arg2)[0].listOfFriends()[0]['age']
I kinda just spent way too long writing all that :v: but hopefully it's a good illustration of the power of the language. Apologies if I've misrepresented anything in PHP, I've been working with PHP4 for the last 6 months (after a 3 year break from that language) and distinctly remember composition simply not being possible.

Also, while it appears trivial, note Python's lack of semicolons and braces for expression/block delimiters. It saves a lot of typing over time, and is one less thing to be thinking about / screwing up. And no, using indents to determine blocks is not a big deal, despite lots of people saying it turns them off. If you indent your PHP/Java/C++/whatever in a readable fashion, you're already doing it the Python way.

bitprophet fucked around with this message at 05:39 on Feb 15, 2008

cLin
Apr 21, 2003
lat3nt.net
Any books or online tutorials you recommend? I am sort of understanding the difference between the two and would like to learn more

gabensraum
Sep 16, 2003


LOAD "NICE!",8,1
cLin: I don't think you can go past the official Python tutorial, at least to start with. The essential reading list linked earlier by m0nk3yz looks good, but I haven't read all of what it suggests, yet.

I think that Python is the most beautiful and clean of the languages, but it has one thing that I really hate - double underscores ("dunders") for name mangling. There has to be a prettier way to do that.

cLin
Apr 21, 2003
lat3nt.net
Thanks guys, links are all bookmarked. I just realized I should start learning javascript as well seeing how the projects I have been working on lately all required some form. But I must learn Python, it looks like a clean language.

Share Bear
Apr 27, 2004

How do I get started writing tests for things in Django?

I've never done testing in code, and my workflow tends to be:

1) Start server
2) Edit views.py or forms.py
3) Refresh browser, test data


I think I could do this better. How?

bitprophet
Jul 22, 2004
Taco Defender
Er. Hate to be all RTFM on you but did you look at the documentation? Go to the Django documentation page and it's the 5th line down under the Reference header :)

Granted, comprehensively testing web apps is a bit tougher because of their nature, but you can still get a lot done with a simple set of unit tests testing object creation/editing/deletion, making sure all your URLs result in HTTP 200s and aren't breaking, and putting doctests on any non-builtin model methods you write (e.g. if you do something like get_sum_of_child_numbers(), do a doctest to ensure it works correctly). So on and so forth.

Share Bear
Apr 27, 2004

bitprophet posted:

Er. Hate to be all RTFM on you but did you look at the documentation? Go to the Django documentation page and it's the 5th line down under the Reference header :)

Granted, comprehensively testing web apps is a bit tougher because of their nature, but you can still get a lot done with a simple set of unit tests testing object creation/editing/deletion, making sure all your URLs result in HTTP 200s and aren't breaking, and putting doctests on any non-builtin model methods you write (e.g. if you do something like get_sum_of_child_numbers(), do a doctest to ensure it works correctly). So on and so forth.

Haha drat I missed it while looking over the documentation page. Thanks.

Cowcatcher
Dec 23, 2005

OUR PEOPLE WERE BORN OF THE SKY
Do you guys know a good validating XML parser that would work on Python 2.5? I can't get PyXML to install, it's asking for 2.4 :/

What I really need is to validate an XML created with minidom in either DOM object, string of file format, I don't care which.

e: I found an unofficial 2.5 release, but I'm not sure if I trust it enough to use it on the server

Cowcatcher fucked around with this message at 20:17 on Feb 6, 2008

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!
PyRXP is probably your best choice.

Cowcatcher
Dec 23, 2005

OUR PEOPLE WERE BORN OF THE SKY

deimos posted:

PyRXP is probably your best choice.

It looks great, but there doesn't seem to be any xsd schema support, it just uses dtd for validating. :(

No Safe Word
Feb 26, 2005

Perhaps we should make a Django megathread, but I thought I'd post this little ditty in here anyway as it can be used outside of Django.

So, for anyone who has played ToME or other roguelikes, you know there are a ton of different monsters, and knowing their characteristics gives you a leg up in the fight. Well, there used to be a ToME monster search page here, but it seems to have gone away. So I wrote a little parser that grabbed that info and put it into a db for a Django web app so I could search on certain criteria looking for monster info.

Well, when I first started building the search page it looked a lot like this:
code:
if request.POST['name']:
    results = results.filter(name__icontains=request.POST['name'])
if request.POST['depth_min']:
    results = results.filter(depth__gte=request.POST['depth_min'])
if request.POST['depth_max']:
    results = results.filter(depth__lte=request.POST['depth_max'])
if request.POST['hp_min']:
    results = results.filter(avg_hp__gte=request.POST['hp_min'])
if request.POST['hp_max']:
    results = results.filter(avg_hp__lte=request.POST['hp_max'])
Which is gross. For one or two fields it would have been fine, but I now have like 40 search criteria on the page and they use the same basic idiom of "if the variable exists in the POST dict, filter on a given field using a specific comparison type with that variable value". So I refactored that to this:

code:
filter_dict = {
        # post var:  (field, compare type)
        'name': ('name', 'icontains'),
        'symbol': ('symbol', 'exact'),
        'depth_min': ('depth', 'gte'),
        'depth_max': ('depth', 'lte'),
        'hp_min': ('avg_hp', 'gte'),
        'hp_max': ('avg_hp', 'lte'),
        # more...
}

        for (post_var, tup) in filter_dict.iteritems():
            if request.POST.has_key(post_var) and request.POST[post_var]:
                kwargs = {'__'.join(tup): request.POST[post_var]}
                results = results.filter(**kwargs)
So now instead of having to add a whole new if branch every time, I can just add in a new entry to the filter_dict with the POST variable name, the DB model field name and the comparison type, and it will work automatically :)

For those a little lost, here's how it (the for loop portion) works:

  • it iterates over the dict, assigning the key to post_var and the tuple of (field name, comparison type) to tup
  • checks to see if the key exists in the dict (has_key), and if it does, makes sure it's not "blank" (the second portion of the and)
  • builds up a temporary one-entry dict called kwargs (short for keyword args), with a key of 'fieldname__comparison' (created by joining the tuple with a '__'), and a value from the POST dict. So, for a filter_dict entry of 'depth_min': ('depth', 'gte'), we would get: {'depth__gte': request.POST['depth_min']}
  • then it filters results using those keyword args, expanded into actual key=value pairs. The ** operator expands dictionaries into key=value pairs. So our previous example would translate to: results.filter(depth__gte=request.POST['depth_min']) (actually it'd translate to whatever the value of that request.POST entry is, but you get the point)

I'm not a huge fan of the whole <fieldname>__<comparison> syntax that Django uses, but in this case it proved extremely useful.

hey mom its 420
May 12, 2007

That's a cool solution!
I also had a similar problem where we were filtering issues in a bug tracking system and at first also has a big if tree, but then I refactored it into this bit of code:
code:
    #check if we're filtering the issues by completed and if we are, filter the selection
    if request.GET.has_key('completed'):
        issues = issues.filter(finished_date__isnull = False if request.GET['completed']=='yes' else True)

    #modify the querydict so it doesn't have completed and page in it
    GET_copy = request.GET.copy()
    if GET_copy.has_key('completed'):
        del GET_copy['completed']
    if GET_copy.has_key('page'):
        del GET_copy['page']

    #filter the issues by what's left
    issues = issues.filter(**dict([(str(key),str(value)) for key,value in GET_copy.items()]))
There are two special values, which are pages (which is for the page you're on) and completed, because we aren't using a completed boolean field in the database but rather we check if finished_date is null or not.
The magic is in the last line, which takes the querystring, turns it into a dict and uses it as arguments for the filter method. So you can do any kind of filtering you want off the bat, for example: ?page=1&issue_type__slug=bug&issue_status__slug=accepted&completed=no

hey mom its 420
May 12, 2007

Also, does anyone know how to switch databases on the fly in Django? Or if that's even possible.
I need that because when unit testing, I supply a JSON fixture that the tests use as sample data. When the tests are run, a temporary database is created and used and destroyed after the tests are done. But I'd like to pull some data from the regular database in the tests. That's because we've moved some setting values from settings.py (in order not to clutter it up too much) to the database and it would be cool to get those settings in the tests because they reference folders on your machine and I want the tests to be portable across machines.

duck monster
Dec 15, 2004

deep square leg posted:

cLin: I don't think you can go past the official Python tutorial, at least to start with. The essential reading list linked earlier by m0nk3yz looks good, but I haven't read all of what it suggests, yet.

I think that Python is the most beautiful and clean of the languages, but it has one thing that I really hate - double underscores ("dunders") for name mangling. There has to be a prettier way to do that.

Yeah I think everyone hates that part. Its like you take a beautiful language and lay a gigantic turd into the middle of all that beauty. But....... Guido knows best. I'm sure he's sitting on his magical throne watching this and saying "Ah Ducks, you'll understand it one day <insert monty python joke>"

duck monster
Dec 15, 2004

:siren: Webware for Python is in beta for 1.0 FINALLY :siren:

This is a great stack for more traditional Tomcat style servelet style development. I love it. Its got a PSP implementation in there (Think PHP or ASP but with python) , a full persistant servlett stack, Kid templates , authentication stacks, OODB abstaction, you name it. Compared with Django and the like , this bad boys a grandfather of the scene, its been that long brewing.

http://www.webwareforpython.org/

Honestly after using this for servlett apps, just mentioning Tomcat gives me the heebee-jeebees. Its just nicer with python.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I don't get the hate for double underscores at all. I think they look neat. And it's got precedent in magic macros like __FILE__ and __LINE__ in .

epswing
Nov 4, 2003

Soiled Meat
On the threading module page, why is it
code:
self.value = value = self.value + 1
and not
code:
self.value = self.value + 1
?

ynef
Jun 12, 2002
Because they're trying to save an extra line. Both the object specific "value" (self.value) and the global variable "value" are affected, and set to "self.value + 1".

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

epswing posted:

On the threading module page, why is it
code:
self.value = value = self.value + 1
and not
code:
self.value = self.value + 1
?

Because he's updating the global value at the same time, seems like a convoluted way of doing it since he's returning it too.

ynef posted:

Because they're trying to save an extra line. Both the object specific "value" (self.value) and the global variable "value" are affected, and set to "self.value + 1".

Yeah but he's returning and assigning to value anyways outside the critical section. You might as well return self.value. :iiam:

deimos fucked around with this message at 19:33 on Feb 10, 2008

epswing
Nov 4, 2003

Soiled Meat
Ok so maybe I'm going blind but I don't see any global variables. I see two class definitions, a counter object and a for loop.

ynef
Jun 12, 2002

epswing posted:

Ok so maybe I'm going blind but I don't see any global variables. I see two class definitions, a counter object and a for loop.

See that variable called "value"? That's global: the very same one is used in both classes. Python can be confusing that way, since the variable doesn't need to be declared to be global in a special way.

epswing
Nov 4, 2003

Soiled Meat
Ok, let me ask this, if
code:
self.value = value = self.value + 1
is changed to
code:
self.value = self.value + 1
and
code:
return value
is changed to
code:
return self.value
am I looking at exactly the same program? Output seems to be the same. Why would they throw in this value variable?

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

epswing posted:

Ok, let me ask this, if
code:
self.value = value = self.value + 1
is changed to
code:
self.value = self.value + 1
and
code:
return value
is changed to
code:
return self.value
am I looking at exactly the same program? Output seems to be the same. Why would they throw in this value variable?

I am pretty sure it might be a remnant from the evolution of the example, ie. a previous version might have just used the global value without the return assignment.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I haven't take the time to analyze the whole thing, but the difference is that in the version as written, the global value is updated while inside the critical section, and then again after it returns. That could be important if two threads try to access it at the same time.

SmirkingJack
Nov 27, 2002
Yesterday Reddit pointed me to "How not to write Python code" and one of the things that caught my eye was the following:

quote:

Use Pythonesque coding pattern
This is very related to the previous item, obviously. Python has some well-known constructs to handle some situations. Get to know and understand them.
An example: as you might know, Python has no switch/case construct. There’s a very neat way to implement this though by simply using a dict and function objects (or lambda functions). An example:
code:
def handle_one():
    return 'one'
def handle_two():
    return 'two'
def handle_default():
    return 'unknown'
cases = {
    'one': handle_one,
    'two': handle_two,
    'three': lambda: 'three',
}
for i in ('one', 'two', 'three', 'four', ):
    handler = cases.get(i, handle_default)
    print handler()
We’re using the dict.get method here, which can take an optional ‘default’ argument. Pretty neat, huh?

I am pretty new to this Python thing and it made me realize that I do not know much about coding in a manner consistent with other Python programmers. Could anyone point out examples of common Python techniques ("this is the way we do switch")?

No Safe Word
Feb 26, 2005

SmirkingJack posted:

Yesterday Reddit pointed me to "How not to write Python code" and one of the things that caught my eye was the following:


I am pretty new to this Python thing and it made me realize that I do not know much about coding in a manner consistent with other Python programmers. Could anyone point out examples of common Python techniques ("this is the way we do switch")?

We do list comprehensions instead of accumulating lists in for loops.

Bad:
code:
new_list = []
for item in some_list:
    new_list.append(item.some_method())
Good:
code:
new_list = [item.some_method() for item in some_list]
That's all I can think of right now. Though as a note I take issue with that post title (and I thought the same thing when I saw it on reddit) - because really it only has like 2 things not to do, and 8 others which are "do this".

edit: also note that you can filter in list comprehensions (though the filter function also works in some cases)

code:
filtered_list = [item for item in original_list if some_predicate(item)]

hey mom its 420
May 12, 2007

How exactly is that variable global? Can someone please explain to me? I would have thought `value` is not put in the global namespace when doing
code:
self.value = value = self.value + 1
but in the method's namespace.

ATLbeer
Sep 26, 2004
Über nerd
This might warrant it's own thread but, I'm having problems with both Python24 and 25 installed on my Mac.

I don't particularly remember installing 25 but, I guess it might have come from my Leopard upgrade. I don't honestly care much which version I am using but, my problem comes from the fact that any type of library or module install I am doing is defaulting into the 2.5 installation directory but, all my scripts are executed by 2.4.4.

Can anyone help me sort out this all?

Should I remove one installation (24 or 25) or how can I at least just get easy_install etc, to use one installation (preferably 24, since I already have a bunch of packages installed there) or migrate my packages over?

I'm a bit dumbfounded right now

No Safe Word
Feb 26, 2005

Bonus posted:

How exactly is that variable global? Can someone please explain to me? I would have thought `value` is not put in the global namespace when doing
code:
self.value = value = self.value + 1
but in the method's namespace.

If it's declared/initialized in the global namespace, it can be accessed/modified by any method. If it's not, then yes it's local to that method. What you may not have seen is:

code:

value = foo

# loads of other stuff

class moo:
    def our_method(self, whatever):
        self.value = value = self.value + 1
        return value
That sets both the instance's value attribute as well as the globally accessible value variable. No it doesn't! You need the global keyword, I'm dumb!

edit: durr :downs:

No Safe Word fucked around with this message at 21:11 on Feb 11, 2008

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
Bonus is right. To modify a global in a local namespace you need to use the global statement.

hey mom its 420
May 12, 2007

No Safe Word: Umm, could you perhaps provide a working example of how that works?
Here's what my interpreter says:
code:
>>> class Moo:
...   def __init__(self):
...     self.value = 0
...   def incme(self):
...     self.value = value = self.value + 1
...
>>> t = Moo()
>>> t.incme()
>>> value
5
>>> t.value
1
>>> t.incme()
>>> t.value
2
I'm pretty sure that
code:
self.value = value = self.value +1
creates a variable called `value` in the method's namespace that overshades the one in the global.

Adbot
ADBOT LOVES YOU

No Safe Word
Feb 26, 2005

Bonus posted:

No Safe Word: Umm, could you perhaps provide a working example of how that works?
Here's what my interpreter says:
code:
>>> class Moo:
...   def __init__(self):
...     self.value = 0
...   def incme(self):
...     self.value = value = self.value + 1
...
>>> t = Moo()
>>> t.incme()
>>> value
5
>>> t.value
1
>>> t.incme()
>>> t.value
2
I'm pretty sure that
code:
self.value = value = self.value +1
creates a variable called `value` in the method's namespace that overshades the one in the global.
That's correct - I didn't look at the context source and just went with the one line you had provided. But now that I'm seeing the source I see that there is no global declaration. Yes, you'd need to use global to actually modify the
value and you would indeed be shadowing the global value, but you can access the value that's in the global scope without the global keyword (you just can't modify it and expect the changes to propagate out of scope).

code:
>>> class Foo:
...     def bar(self):
...             print baz
...
>>> baz = 4
>>> f = Foo()
>>> f.bar()
4
>>> baz = 6
>>> f.bar()
6
So, basically that link is dumb :) If the first thing it's doing is assigning to the variable, it inherently loses whatever value it had in the global scope and just becomes a local variable with the same name, shadowing anything that might want to access the global variable.

  • Locked thread