Python's use of namespaces is, as we all quite know, "one honking great idea!"; 
and i must wholeheartedly agree, however, accessing and declaring variables 
living in python namespaces is a kludge at best, and a malevolent obfuscation 
at worst!

============================================================
 MODULE LEVEL VARIABLES
============================================================ 

Take module level variables for example. When reading over some source code we 
really have no idea in which namespace a variable lives. Consider the following:

count = 0
class Blah:
    def meth():
        for x in range(100):
            count = x
     
Where is count living? 

Of course in this simplistic example we can see that count is @ module level, 
but what about a module with hundreds or even thousands of lines of code, 
multiple classes, multiple functions, constants out the yin-yang... yes that 
abomination Tkinter does comes to mind, but i digress... no one can be expected 
to remember every single variable MUCH LESS remember every variable's scope 
also, this is madness!

============================================================
 THE GLOBAL FOLLY 
============================================================

The global statement is not only useless but just serves to confuse people who 
have experience with languages that have "real" global variables -- not that i 
am promoting the use of "real" global mind you, i find them to be the crutch of 
inexperienced programmers! 

In the "solution" section below i provide an outline of how to remove the 
global statement. I just want to rant about it here.

============================================================
 CLASS LEVEL AND INSTANCE LEVEL VARIABLES
============================================================

There are two reasons why i just hate the manner in which python syntax forces 
me to create and accesses class level and instance level variables:

   1. class level variable creation requires
      no qualification whist access does!
      
   2. self is used confusingly for accessing
      both when self should only be used to
      access instance level variables!
  
Consider this interactive session:

>>> class Foo(object):
        cv = 0 # Class variable.
        def __init__(self):
                Foo.cv += 1
                print Foo.cv    
>>> f1 = Foo()
1
>>> f2 = Foo()
2
>>> f3 = Foo()
3
>>> ...

So python will allow us to create a class level variable WITHOUT qualification 
however we must qualify the variable to modify it? Okay, okay, we could infer 
the scope from indention but what about consistency? I would prefer to qualify 
the variable in both cases! Besides, GvR had the Cojones to force us to write 
"self" as the first argument to EVERY SINGLE instance method under the 
justification of "self documenting code" when any sane person could intuit that 
"self" belongs to the INSTANCE only. Not to mention that Python has visual 
scoping in the form of forced indentation. GvR needs to answer for this crime 
against py-manity! But i digress!!!

Oh, but just wait, the real strange stuff is just around the corner. Enter the 
twilight zone if you dare!

>>> hasattr(Foo, 'cv')
True

Okay, i expected that but...

>>> hasattr(f1, 'cv')
True

How the hell can an INSTANCE have an attribute named "cv" when "cv" is class 
level? Can you can hear the eery music?, can you see Rod's toothy grin?, I 
thought so! 

Hell, since we're already falling "head-over-heels" down the rabbit hole we 
might as enjoy the visuals of a peep through the looking glass of insanity!

>>> class Bar(object):
        cv = 0 # Class variable.
        def __init__(self):
                self.cv += 1
                print self.cv           
>>> b1 = Bar()
1
>>> b2 = Bar()
1
>>> b3 = Bar()
1
>>> ...

Why did Python NOT throw an error? How could "self.cv" possibly execute when 
there is no instance variable named "cv"? 

============================================================
 SOLUTION
============================================================

It is my strong opinion that all "unqualified" variables must be local to the 
containing block, func/meth, class, or module. To access any variable outside 
of the local scope a programmer MUST qualify that variable with the func, 
class, or module identifiers. Consider the following examples 

# Module: example.py

count = 0

for x in range(100):
    # Increment the module level variable count.
    example.count += 1

def increment():
   # Create a local variable named count.
   count = 0
   # Increment the module level variable named count.
   # No need for stupid global statement or guessing 
   # because our code will be self documenting! (Then 
   # Why the hell am i writing this comment! :-P")
   example.count += 1 
   # Create a new module level variable named foo
   example.foo = "foo"
   # return the local variable count. 
   return count
   
class Foo():
    # Declare a class level variable named "var". Must use
    # class identifier for both declaration and access! 
    Foo.var = 0 
    def __init__(self):
        # Increment the class level variable "var" by one. If
        # we had foolishly tried to access var using "self" we
        # have suffered the NameError.
        Foo.var += 1 
        # If we want to assign variables at the instance level
        # we use self. 
        self.var = "blah" # Instance variable

 *school-bell-rings*
 
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to