473,405 Members | 2,338 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

utility functions within a class?

I might be missing something obvious here, but I decided to experiment
with writing a program that involves a class, so I'm somewhat new to
this in Python.

Anyway, what is the best way to create a function (A) within a class
that another function (B) can use? Function A is not something that an
instance will ever call, so I figure it's a choice between static or
class methods, but I don't know which one, or if this is even the right
approach.

Specifically, I am writing a class that defines methods that wrap string
arguments inside HTML elements, and ultimately creates and HTML page. I
know there are probably a ton of programs like this already, but this is
just to give me something to do with Python.

So I have a generate() method that will create the final HTML file once
you are done creating elements. First it will create a string with the
proper DTD, then it will append the <head> element and the <body>
element, wrapped in the <html> element.

Rather than have the generate() function do all the work, I thought I
could write two utility functions to generate the head and body
elements. These would simply wrap the element names around some
pre-defined text (for the head) and around all the other elements (for
the body).

So I'm wondering, how would I define these two functions? They would be
called from the generate method solely for the purpose of creating the
head and body blocks.

Thanks!
May 8 '06 #1
22 5276
It sounds like all you want is some encapsulation, the following makes
methods __head__ and __body__ "private" - the double underscores are
important. I'd suggest reading the Object bits of the python tutorial
also.

class HTMLWrapper:

def generate(self, ...):
...
self.__head__(foo)
...
self.__body__(bar)
...

def __head__(self, ...):
...

def __body__(self, ...):
...

May 8 '06 #2
You do *NOT* want to put double-underscores before and after a method
name. That does not indicate a private method, it indicates a "magic
method" -- something that has special meaning to Python. Thus, you
have special methods like __init__(), __len__(), __getattr__(),
__setattr__(), etc; all of these methods may be called *by Python* in
certain specific circumstances, and allow you to customize how your
objects respond to those circumstances.

Naming methods that are *not* special "magic methods" using this naming
convention is a very bad idea.

On the other hand, methods with only a single or double *leading*
underscore, and no trailing underscore(s), can be considered to express
some degree of privacy. A single underscore, by convention, indicates
an internal method or attribute, and that name will typically not be
exported. A double underscore will trigger minimal name mangling; not
only will the name not be exported, but it will be converted to
_<classname>__<name>, making it a bit more difficult to access from
outside the class. (Access inside the class is via the unmangled
name.)

In this circumstance, I'd probably have methods _generate_head(self)
and _generate_body(self). Don't mess with making them class/static
methods unless it's important to be able to access them when you don't
have any instance of the class available (and if you're calling them
from inside a regular method, then you *do* have an instance
available). Even if you don't end up referring to self or any instance
attributes within the method, it's simpler to keep it as a normal
method.

--Jeff Shannon

May 8 '06 #3
> You do *NOT* want to put double-underscores before and after a method
name. That does not indicate a private method, it indicates a "magic
method"


WHOOPS!!

Sorry, I haven't touched python for a few months and just started
working on a script this morning so was going to post my own question
when I got sidetracked answering this thread. I guess that might be a
good reason not to use underscores as significant syntax.

Cheers,
-B

May 8 '06 #4
je*********@gmail.com wrote:
Even if you don't end up referring to self or any instance
attributes within the method, it's simpler to keep it as a normal
method.


Thanks, that makes sense to me! So basically just create them as
methods, and if I want a little 'privacy' I can lead with an underscore?
Somehow that sounds like the right idea... :)
May 8 '06 #5
je*********@gmail.com wrote:
Even if you don't end up referring to self or any instance
attributes within the method


Hmm, follow-up: I *do* plan to refer to instance attributes inside these
methods (self.something), but does that require that they be instance
methods, or can they still reference 'self' since they are inside the class?

They won't be called directly from an instance, which is why I wondered
about making them static or class methods, but can static or class
methods use self, or does it have to be an instance method in that case?
May 8 '06 #6
John Salerno wrote:
je*********@gmail.com wrote:
Even if you don't end up referring to self or any instance
attributes within the method


Hmm, follow-up: I *do* plan to refer to instance attributes inside these
methods (self.something), but does that require that they be instance
methods, or can they still reference 'self' since they are inside the class?

They won't be called directly from an instance, which is why I wondered
about making them static or class methods, but can static or class
methods use self, or does it have to be an instance method in that case?


Ugh, sorry about another post, but let me clarify: In these utility
functions, I need to refer to an attribute of an instance, but these
functions will be called from another method in the class, not from the
instance itself. Is this even possible, or would 'self' have no meaning
when used this way?
May 8 '06 #7
John Salerno wrote:
Ugh, sorry about another post, but let me clarify: In these utility
functions, I need to refer to an attribute of an instance, but these
functions will be called from another method in the class, not from the
instance itself. Is this even possible, or would 'self' have no meaning
when used this way?


I'm having trouble deciphering what this bit means - "but these
functions will be called from another method in the class, not from the
instance itself", I don't think it makes sense.

If you're calling something in a class method then there must be an
instance of that class, instantiated as an object, in order to make the
call in the first place.

'self' does have meaning inside a class, you use it when you want to
call another method within the same class. Python can then fill in the
self reference in the arguments to the callee for you as it does when
you call a method from outside of the class by qualifying with the
instance name.
inside class A:
self.blah(args)
outside class A:
a_A = A()
a_A.blah(args)

Cheers,
-B
(Hope I've got this one right)

May 8 '06 #8
bl*************@gmail.com wrote:
I'm having trouble deciphering what this bit means - "but these
functions will be called from another method in the class, not from the
instance itself", I don't think it makes sense.


Yeah, I'm starting to see that as I tried to implement it. Here's what I
came up with, which works:

def generate(self, filename):
self.head = self.generate_head()
self.body = self.generate_body()

So the two generate_* methods are called from within another class
method, and it seemed necessary to still call them from an instance.
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.
May 8 '06 #9
John Salerno wrote:
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.


Yep, so you want to encapsulate the functionality that those methods
provide, which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.

In python, as discussed earlier :), you can make them semi-private by
using the '__method_name' syntax. The thing is that python doesn't
strictly enforce this privacy, code outside of your object can still
call these methods because python just mangles the internal method name
slightly. See
http://docs.python.org/tut/node11.ht...00000000000000
for more detail.

Cheers,
-B

May 8 '06 #10
bl*************@gmail.com wrote:
John Salerno wrote:
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.


Yep, so you want to encapsulate the functionality that those methods
provide, which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.


But it's right that they should still be regular instance methods? So
from within the class I still call them as self._generate_head(), etc.?
May 8 '06 #11
John Salerno wrote:
bl*************@gmail.com wrote:
John Salerno wrote:
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.


Yep, so you want to encapsulate the functionality that those methods
provide, which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.


But it's right that they should still be regular instance methods? So
from within the class I still call them as self._generate_head(), etc.?


I tried the underscore method, but I was still able to call it as a
regular instance method in the interpreter. Is that what's supposed to
happen?
May 8 '06 #12
John Salerno wrote:
John Salerno wrote:
bl*************@gmail.com wrote:
John Salerno wrote:
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.

Yep, so you want to encapsulate the functionality that those methods
provide, which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.


But it's right that they should still be regular instance methods? So
from within the class I still call them as self._generate_head(), etc.?


I tried the underscore method, but I was still able to call it as a
regular instance method in the interpreter. Is that what's supposed to
happen?


If you called it, "__generate_head" you'd get more of what you expect.

The Python philosophy is "we're all adults here," and the single leading
underscore is meant to tell other users that the method is not for
general use. Remember, you can't stop a user who insists on making
mistakes. The double leading underscore is really meant for something
else (names in "mixin" classes that don't accidentally collide with
names in subclasses, for example).

IMO, distutils, for example, over-uses the double leading underscore
names; it makes it awkward for me to get to information that I'd like
to obtain. The double leading underscore should be there if there is
no reasonable use to getting to this info. I suspect leading double
underscore names are more frequently written by Java and C++ fugitives
who still have the "save the user from himself" attitude.

--Scott David Daniels
sc***********@acm.org
May 8 '06 #13
Dennis Lee Bieber wrote:
tOn Mon, 08 May 2006 14:04:34 GMT, John Salerno
<jo******@NOSPAMgmail.com> declaimed the following in comp.lang.python:
I tried the underscore method, but I was still able to call it as a
regular instance method in the interpreter. Is that what's supposed to
happen?


Single underscores are a convention/signal to the programmer that
"this method/attribute" is considered "private" and should only be used
by other methods within the class that defined it. The language does no
enforcement of usage. For example:


I see. But isn't there something about a single leading underscore that
doesn't import when you use from X import *? Or am I thinking of
something else? Is that also the double underscore?
May 8 '06 #14
John Salerno wrote:
Dennis Lee Bieber wrote:
... Single underscores are a convention/signal to the programmer that
"this method/attribute" is considered "private" and should only be used
by other methods within the class that defined it. The language does no
enforcement of usage....


I see. But isn't there something about a single leading underscore that
doesn't import when you use from X import *? Or am I thinking of
something else? Is that also the double underscore?


That has to do with module contents, and is a completely separate issue.
If you define a module with a variable name '__all__' which is a list
(or tuple) of strings, only module elements with those names will be
imported with a "from module import *". If you fail to define the
'__all__' element, all names which do not start with an underscore will
be imported.

--Scott David Daniels
sc***********@acm.org
May 8 '06 #15
Scott David Daniels wrote:
John Salerno wrote:
Dennis Lee Bieber wrote:
... Single underscores are a convention/signal to the programmer that
"this method/attribute" is considered "private" and should only be used
by other methods within the class that defined it. The language does no
enforcement of usage....


I see. But isn't there something about a single leading underscore
that doesn't import when you use from X import *? Or am I thinking of
something else? Is that also the double underscore?


That has to do with module contents, and is a completely separate issue.
If you define a module with a variable name '__all__' which is a list
(or tuple) of strings, only module elements with those names will be
imported with a "from module import *". If you fail to define the
'__all__' element, all names which do not start with an underscore will
be imported.

--Scott David Daniels
sc***********@acm.org


Thanks, that's what I was thinking of. So it doesn't apply to the
contents within a class, just top-level contents?
May 8 '06 #16
John Salerno wrote:
Scott David Daniels wrote:
John Salerno wrote:
... But isn't there something about a single leading underscore
that doesn't import when you use from X import *? Or am I thinking of
something else? Is that also the double underscore?


That has to do with module contents, and is a completely separate issue.
If you define a module with a variable name '__all__' which is a list
(or tuple) of strings, only module elements with those names will be
imported with a "from module import *". If you fail to define the
'__all__' element, all names which do not start with an underscore will
be imported.


Thanks, that's what I was thinking of. So it doesn't apply to the
contents within a class, just top-level contents?


Precisely, a "from ... import *" only creates a bunch of names bound to
a module's top-level contents (at the time of execution of the
"from ... import *"), and does not affect anything about those bound
values (except, of course, the refcount).

--
-Scott David Daniels
sc***********@acm.org
May 9 '06 #17
John Salerno wrote:
John Salerno wrote:
je*********@gmail.com wrote:
Even if you don't end up referring to self or any instance
attributes within the method

Hmm, follow-up: I *do* plan to refer to instance attributes inside
these methods (self.something), but does that require that they be
instance methods, or can they still reference 'self' since they are
inside the class?

They won't be called directly from an instance, which is why I
wondered about making them static or class methods, but can static or
class methods use self, or does it have to be an instance method in
that case?

Ugh, sorry about another post, but let me clarify: In these utility
functions, I need to refer to an attribute of an instance,


So you want ordinary methods.
but these
functions will be called from another method in the class, not from the
instance itself.
yes, they will:

class Parrot(object):
def _func1(self, whatever):
print whatever

def talk(self):
self._func1('vroom')
Is this even possible, or would 'self' have no meaning
when used this way?


You probably noticed that 'self' (or whatever you name it - but better
to stick to convention) *must* be defined as the first param of a
'method'. The reason for it is that what we commonly call 'methods' are
in fact plain Python functions. It's only when they are looked up on an
instance that they are wrapped into a 'method' object (read about the
descriptor protocol to learn how...), that in turn calls the function,
passing it the instance as first param.

For saying it short (warning: over-simplification ahead), the usual
method call idiom:

myObj.myMethod(arg)

is syntactic sugar for:

myObj.__class__.myMethod(myObj, arg)
HTH.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 10 '06 #18
John Salerno wrote:
bl*************@gmail.com wrote:
I'm having trouble deciphering what this bit means - "but these
functions will be called from another method in the class, not from the
instance itself", I don't think it makes sense.

Yeah, I'm starting to see that as I tried to implement it. Here's what I
came up with, which works:

def generate(self, filename):
self.head = self.generate_head()
self.body = self.generate_body()

So the two generate_* methods are called from within another class
method,


here, generate() is *not* a class method, it's an instance method (which
is the default).
and it seemed necessary to still call them from an instance.
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.


Yeps, that's pretty common in any OO language. In most mainstream OOPLs,
these methods would have the 'protected' access restriction modifier. In
Python, we rely on the convention that an attribute whose name is
prefixed with a single underscore is an implementation detail - not part
of the API - and should not be called by client code. Just renaming
these two methods is enough to warn users of your code that they're on
their own if they start messing with them.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 10 '06 #19
bl*************@gmail.com wrote:
John Salerno wrote:
What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.

Yep, so you want to encapsulate the functionality that those methods
provide,

which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.

In python, as discussed earlier :), you can make them semi-private by
using the '__method_name'


Blair, please, don't give bad advices. The 'double-leading-underscore'
stuff has some side-effects (name-mangling), and is meant to protect an
attribute from accidental overloading. The convention for 'protected'
attributes (which should really be named 'implementation attributes') is
a *single* leading underscore.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 10 '06 #20
John Salerno wrote:
John Salerno wrote:
bl*************@gmail.com wrote:
John Salerno wrote:

What I originally meant was that they would not be called from an
instance *outside* the class itself, i.e. they won't be used when
writing another script, they are only used by the class itself.
Yep, so you want to encapsulate the functionality that those methods
provide, which is the whole point of building them in a class in the
first place. And you want them to be private to the class so that they
do not form part of the classes public/external interface.

But it's right that they should still be regular instance methods? So
from within the class I still call them as self._generate_head(), etc.?

I tried the underscore method, but I was still able to call it as a
regular instance method in the interpreter. Is that what's supposed to
happen?


Yes. Language-inforced access restriction is totally useless (and is
quite easy to defeat in C++ and Java FWIW). Python's philosophy is that
programmers are not braindead monkey-coders that must be protected
(pardon the pun) from their own stupidity. There's no way to idiot-proof
a code anyway, so why bother ? The single-underscore prefix means
'implementation, don't touch or else', and this is quite enough. Most
python programmers won't touch it - unless they have perfectly valid
reasons to do so (yes, it happens), and then they will implicitely
accept the consequences.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 10 '06 #21
bruno at modulix wrote:
The convention for 'protected'
attributes (which should really be named 'implementation attributes')


FWIW, I agree. When I hear 'protected attribute' I think of an attribute
that can only be used within its class and subclasses of it.
May 10 '06 #22
bruno at modulix wrote:
but these
functions will be called from another method in the class, not from the
instance itself.


yes, they will:

class Parrot(object):
def _func1(self, whatever):
print whatever

def talk(self):
self._func1('vroom')
HTH.


yes, all your posts did help...this is exactly what i ended up doing,
and i see now why i needed to make them regular methods, despite the
fact that they weren't used outside the class (because the instance was
still used *inside* the class to call them)
May 10 '06 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less...
7
by: Bora | last post by:
I usually find that a number of unrelated classes require the same kind of operations. However, I don't want to duplicate code in multiple places. In Java, I've seen those "Utility Classes",...
5
by: Neil Zanella | last post by:
Hello, I need to access some user defined utility functions from within my ASP.NET pages. I wonder whether there is a way to do this. I do not want to use inheritance. I just want to be able to...
7
by: Jim Strathmeyer | last post by:
So, right now I have a class that is basically utility functions; it's methods are all static because there is no class data, and I would never create an object of this class. So I call these...
4
by: Jeff User | last post by:
Hi all Developing C# web apps, .net1.1 I have gotten in habit of placing commonly used (interface) functions in my base page. However, some apps I work on use a seperate "Utility" class...
14
by: Jess | last post by:
Hello, I learned that there are five kinds of static objects, namely 1. global objects 2. object defined in namespace scope 3. object declared static instead classes 4. objects declared...
5
by: Kurt Jakobsen | last post by:
Hello, I have a utility class that do some db queries that are used by independent pages. From one of the utility functions I would like to return variables back to the aspx page. In old C this...
6
by: Marco | last post by:
One of the things I like about C++ is that it doesn't force you to create fake "objects" in the OO sense. We had a debate at the office about the "right" way to encapsulate related utility...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.