What is the naming convention for accessor of a 'private' variable?

Chris Rebert clp2 at rebertia.com
Wed Nov 18 22:32:03 EST 2009


On Wed, Nov 18, 2009 at 7:04 PM, Peng Yu <pengyu.ut at gmail.com> wrote:
> On Wed, Nov 18, 2009 at 8:47 PM, Chris Rebert <clp2 at rebertia.com> wrote:
>> On Wed, Nov 18, 2009 at 6:27 PM, Peng Yu <pengyu.ut at gmail.com> wrote:
>>> http://www.python.org/dev/peps/pep-0008/
>>>
>>> The above webpage states the following naming convention. Such a
>>> variable can be an internal variable in a class. I'm wondering what is
>>> the naming convention for the method that access such variable.
>>>
>>>    - _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
>>>      import *" does not import objects whose name starts with an underscore.
>>
>> If there's a method to access the variable, then it's not all that
>> private, is it?
>> Accessor methods are not Pythonic. Just make the attribute public by
>> not prefixing it with an underscore.
>>
>> See also "Python is Not Java":
>> http://dirtsimple.org/2004/12/python-is-not-java.html
>
> I don't quite understand the following paragraph from the above
> webpage. Would you please give me an example to help me understand it?
>
> "Here's what you do. You write a function that contains a function.
> The inner function is a template for the functions that you're writing
> over and over again, but with variables in it for all the things that
> vary from one case of the function to the next. The outer function
> takes parameters that have the same names as those variables, and
> returns the inner function. Then, every place where you'd otherwise be
> writing yet another function, simply call the outer function, and
> assign the return value to the name you want the "duplicated" function
> to appear. Now, if you need to change how the pattern works, you only
> have to change it in one place: the template."

#untested off-the-cuff example:

from time import time

def add_timing(func): # takes a function as an argument
    """Wraps functions so they output their execution time when called"""
    def wrapper(*args, **kwargs): #defines a new function
        start = time()
        # thanks to closures, we can access func here
        result = func(*args, **kwargs) # have the new function call
the given function
        end = time()
        duration = end-start
        print "Call to", func.__name__, "took", duration, "seconds"
        return result
    return wrapper # return the new function so that it can replace
the function it calls

def long_calculation(x, y, z):
    # some code

long_calculation = add_timing(long_calculation)

print long_calculation(1, 7, 42)

#Example output:
#Call to long_calculation took 135.5 seconds
#99

Now imaging applying add_timing to multiple functions and note the
amount of code you'd save and how the unrelated concerns of timing and
mathematical calculation (or whatever the functions you apply
add_timing() to do) would then be cleanly separated.
The same technique can be applied to logging and other repetitive code
to factor it out.
It's sort of like aspect-oriented programming, but not as kludgey.

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list