[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

helper function in a class' namespace

Helmut Jarausch

1/31/2008 7:51:00 PM

Hi,

the following code works fine

def Helper(M) :
return 'H>'+M

class A(object):
def __init__(self,Msg) :
print Helper(Msg)

B=A('ZZ')

but the Helper function is in the module's namespace.

I'd like to put it into class A's namespace.
Note, the Helper function doesn't need access to any instance attributes.

The first variant

class A(object):
def Helper(M) :
return 'H>'+M
def __init__(self,Msg) :
print Helper(Msg)

doesn't work since Python is looking for a global function Helper (why?)

The alternative

class A(object):
def Helper(M) :
return 'H>'+M
def __init__(self,Msg) :
print A.Helper(Msg)

doesn't work either since now the first argument to A.Helper must be 'A'.

So, isn't it possible to have a helper function in the namespace of a class
without (the overhead of) passing a 'self' or a 'cls' parameter?

Probably I'm hurt by my C++ history.

Many thanks for your help,
Helmut.



--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany
4 Answers

Stargaming

1/31/2008 8:06:00 PM

0

On Thu, 31 Jan 2008 20:51:23 +0100, Helmut Jarausch wrote:

> Hi,
>
> the following code works fine
>
> def Helper(M) :
> return 'H>'+M

String concatenation is generally considered unpythonic, better use
string interpolation::

'H> %s' % (M,)

> class A(object):
> def __init__(self,Msg) :
> print Helper(Msg)
>
> B=A('ZZ')

Watch out your names -- they could confuse other Python programmers
introspecting your namespaces! Names bound to objects should generally be
lowercase (argument ``msg``, object ``b``, argument ``m``, function
``helper``). For details on what the Python community has agreed on is
"good style," see the `Style Guide <http://www.python.org...
pep-0008/>`_.

> but the Helper function is in the module's namespace.

Where's the problem? If it is "I don't want Helper to be visible", just
use this convention: "Names beginning with an underscore are private.
Better keep your fingers off."

> I'd like to put it into class A's namespace. Note, the Helper function
> doesn't need access to any instance attributes.
>
> The first variant
>
> class A(object):
> def Helper(M) :
> return 'H>'+M
> def __init__(self,Msg) :
> print Helper(Msg)
>
> doesn't work since Python is looking for a global function Helper (why?)

Because in the scope of the ``__init__`` function, the name ``Helper`` is
not bound. It then jumps out to the global scope.

> The alternative
>
> class A(object):
> def Helper(M) :
> return 'H>'+M
> def __init__(self,Msg) :
> print A.Helper(Msg)
>
> doesn't work either since now the first argument to A.Helper must be
> 'A'.
>
> So, isn't it possible to have a helper function in the namespace of a
> class without (the overhead of) passing a 'self' or a 'cls' parameter?

Of course it is! You can decorate certain functions with the
`staticmethod <http://docs.python.org/lib/built-in-funcs.html#...`_
wrapper, which will do exactly what you wanted::

class A(object):
@staticmethod
def helper(m):
return 'H>%s' % (m,)
def __init__(self, msg):
print A.helper(msg) # or self.helper


HTH,

Steven D'Aprano

1/31/2008 10:39:00 PM

0

On Thu, 31 Jan 2008 20:05:44 +0000, Stargaming wrote:

> String concatenation is generally considered unpythonic, better use
> string interpolation::
>
> 'H> %s' % (M,)

String concatenation is significantly faster than string interpolation.

>>> import timeit
>>> timeit.Timer("'H> %s' % M", "M = 'abcdef'").repeat()
[1.3407769203186035, 0.69128704071044922, 0.56362509727478027]
>>> timeit.Timer("'H> ' + M", "M = 'abcdef'").repeat()
[0.69647812843322754, 0.69620108604431152, 0.65643787384033203]

The danger with string concatenation comes from building up a string
piece by piece: even though a single + is faster than a single %, a dozen
concats will likely be MUCH slower than a single &.

Also, the tuple above is totally unnecessary. 'H> %s' % M will work fine.


--
Steven

Arnaud Delobelle

1/31/2008 10:46:00 PM

0

On Jan 31, 10:39 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Thu, 31 Jan 2008 20:05:44 +0000, Stargaming wrote:
> > String concatenation is generally considered unpythonic, better use
> > string interpolation::
>
> >     'H> %s' % (M,)
[...]
> Also, the tuple above is totally unnecessary. 'H> %s' % M will work fine.

...except if M is a tuple:

>>> M = 'spam', 'eggs'
>>> 'H> %s' % (M,)
"H> ('spam', 'eggs')"
>>> 'H> %s' % M
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting


Pedantically yours,

--
Arnaud

Arnaud Delobelle

1/31/2008 10:54:00 PM

0

On Jan 31, 8:05 pm, Stargaming <stargam...@gmail.com> wrote:
[...]
> > class A(object):
> >    def Helper(M) :
> >      return 'H>'+M
> >    def __init__(self,Msg) :
> >      print Helper(Msg)
>
> > doesn't work since Python is looking for a global function Helper (why?)
>
> Because in the scope of the ``__init__`` function, the name ``Helper`` is
> not bound. It then jumps out to the global scope.

But it is 'Helper' bound in the scope of the *definition* of __init__,
hence you *could* write:

>>> class A(object):
... def _helper(x): return '<<%s>>' % x
... def __init__(self, msg, _helper=_helper):
... print _helper(msg)
... del _helper
...
>>> A('spam')
<<spam>>
<__main__.A object at 0x70170>

Confusingly yours,

--
Arnaud