473,399 Members | 3,603 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,399 software developers and data experts.

Implementing class attribute access methods via pseudo-function overloading.

Hi All,

I've seen lots of code in which the attributes of a class are accessed and
modified using two separate methods. For example:

class Problems:
def __init__( self, refNum ):
self._refNum = refNum
self._title = ""
self._problem = ""

def setTitle( self, title="" ):
self._title = title

def setProblem( self, problem="" ):
self._problem = problem

def getTitle( self ):
return self._title

def getProblem( self ):
return self._problem

I prefer to use the following implementation that simulates function
overloading (an OOP feature that I like and that Python does not support):

class Problems:

def __init__( self, refNum ):
self._refNum = refNum
self._title = ""
self._problem = ""

def title( self, title=None ):
if title == None:
return self._title
self._title = title

def problem( self, problem=None ):
if problem == None:
return self._problem
self._problem = problem

This approach reduces the number of required accessor methods by 50% (bit of
an obvious statement I know). I also think that it this allows you to write
cleaner looking code. For Example:

theProblem = Problems( "12345" )

print "Title: ", theProblem.title()
print "Problem: ", theProblem.problem()

theProblem.title( "Java affecting adoption of Python." )
theProblem.problem( "Developers are more inclined to use Java instead of
Python due to the fact that Java is seen as a defacto standard." )

print "Title: ", theProblem.title()
print "Problem: ", theProblem.problem()
Am I correct in stating that Python does not support function overloading?
Have I been hiding under a rock and not noticed the thousands of examples
that illustrate this approach?
Any comments are welcome!
Cheers!!
Dermot Doran
EMC2 GTS Solutions Level 2
Office: +31-20-7768439
Mobile: +31-6-55815258

Jul 18 '05 #1
7 2153
Do**********@emc.com wrote:
I've seen lots of code in which the attributes of a class are accessed and
modified using two separate methods. For example:


I think this is a great illustration of what properties can be used for:

http://www.python.org/2.2.2/descrintro.html#property

Then you can reduce your class to:

class Problems:
def __init__(self, refNum):
self._refNum = refNum

This is a LOT less code.

And use theProblem.title, theProblem.problem without any apparent
function calls. As far as those fancy accessor methods go, YAGNI. If you
do need them later, you can always add them:

def _get_title(self):
return self._title

def _set_title(self, title):
assert isinstance(title, basestring)
self._title = title

title = property(_get_title, _set_title)

I would much rather use theProblem.title = "the title" rather than
theProblem.title("the title").
--
Michael Hoffman
Jul 18 '05 #2
Do**********@emc.com wrote:
def title( self, title=None ):
if title == None:
return self._title
self._title = title


You probably meant
def title( self, title=None ):
if title == None:
return self._title
else:
self._title = title

or every read access would clear the attribute.

1. Some people dislike methods that do very different things depending
on the parameters. These are difficult to explain. Though in your case,
one central explanation and links from all the methods should be enough.

2. None is often a useful value, so perhaps you should use a module
local variable like _GetValue (actual value is irrelevant)
def title (self, title = _GetValue):

Daniel
Jul 18 '05 #3
> Am I correct in stating that Python does not support function overloading?
Have I been hiding under a rock and not noticed the thousands of examples
that illustrate this approach?
No, you are basically right - there is no implicit type-based dispatch in
python. There are some recipes for that, but basically they do the same
you to - check for arguments types, and dispatch accordingly
Any comments are welcome!


Why don't you use properties? That even spares you the () for accessing
variables, and allows direct left-hand-side assignment:

class Foo(object):
def __init__(self):
self._bar = "bar"

def _g_bar(self):
return self._bar

def _s_bar(self, value):
self._bar = value

bar = property(_g_bar, _s_bar)

f = Foo()

print f.bar
f.bar = "baz"

print f.bar
I really prefer that over all other mechanisms, and it allows for bar not
beeing simply stored in the object itself, but instead e.g. fetched lazily
from a database or received/transmitted over a network.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #4
Do**********@emc.com wrote:
Am I correct in stating that Python does not support function
overloading? Have I been hiding under a rock and not noticed the
thousands of examples that illustrate this approach?


Have you considered writing your example this way:

class Problems:
def __init__( self, refNum ):
self._refNum = refNum
self.Title = ""
self.Problem = ""

Now you can write your code as:

theProblem = Problems( "12345" )

print "Title: ", theProblem.Title
print "Problem: ", theProblem.Problem

theProblem.Title = "Java affecting adoption of Python."
theProblem.Problem = '''Developers are more inclined to use Java instead of
Python due to the fact that Java is seen as a defacto standard.'''

This is much clearer than wrapping your attributes up in accessor and
mutator functions and doesn't lose you *anything*. If your code ever
evolves to the point where you need to intercept the attribute access or
mutation then you simply change the affected attributes into properties,
but there is no need to make them properties until this happens.

Python does support function overloading (if you care to write a library
that implements it), but in general it isn't needed. Some languages use
overloading primarily as a means of specifying default arguments (in fact
that is all you did in your example) and Python already has default
arguments. Alternatively you might use overloading to allow different types
to be passed to a function, but Python will already let you do this. If the
function implementations are significantly different then it may mean that
overloading isn't appropriate anyway. If the function implementations are
largely the same then you may be able to share the definition in Python,
possibly with a line or two to sort out the argument types.

It can often be clearer to use different names for functions instead of
overloading them as the names can be used to hint at the type of argument
expected. Doing it this way also means that you can 'overload' on semantics
rather than just the type.

For example consider the function buildFrobozz(x) which I want to overload
to accept either a string or a filename. Oops! I can't use overloaded
functions for that, I have to call my methods buildFrobozzFromString(s) and
buildFrobozzFromFilename(fname). Now I add another function that builds a
frobozz from an open file. Calling it buildFrobozzFromFile(f) doesn't seem
to me to be losing anything.

(Actually, I would probably make all of those class methods of the Frobozz
class and call them fromString, fromFilename, fromFile for a bit more
brevity.)

Jul 18 '05 #5
Daniel Dittmar wrote:
Do**********@emc.com wrote:
def title( self, title=None ):
if title == None:
return self._title
self._title = title


You probably meant
def title( self, title=None ):
if title == None:
return self._title
else:
self._title = title

or every read access would clear the attribute.


No, the OP was right here--the return occurs before the attribute can be
set.
--
Michael Hoffman
Jul 18 '05 #6
>>>>> "Duncan" == Duncan Booth <du**********@invalid.invalid> writes:

Duncan> theProblem.Title = "Java affecting adoption of Python."

....

Duncan> This is much clearer than wrapping your attributes up in
Duncan> accessor and mutator functions and doesn't lose you
Duncan> *anything*. If your code ever evolves to the point where
Duncan> you need to intercept the attribute access or mutation
Duncan> then you simply change the affected attributes into
Duncan> properties, but there is no need to make them properties
Duncan> until this happens.

I felt this is something worth highlighting - in Java you *need* to
implement accessors because you can't convert direct attribute access
to accessor methods if/when you are start to second-guess the
design. In Python (and some other languages) you don't need to do
that.

That's yet another "guilt" that must be washed away from aspiring
Pythonista's minds, just like while 1, if cond: break...

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #7
> Am I correct in stating that Python does not support function overloading?

Technically, yes. Two methods with the same name can't coexist in the
same namespace. Overloading makes sense in C++ because the compiler
is able to decide which function to use at compile time based on
number and type of arguments. Python is (a) not compiled and (b) not
statically typed, so overloading as a part of the language makes a lot
less sense.

You yourself have demonstrated why overloading isn't necessary: A
function can implement its own dispatch mechanism when invoked, based
on inspection of the arguments passed to it.

Additionally, considering that one can write functions with totally
arbitrary calling sequences,

def foo(*args, **keywords):
...

....you can go _beyond_ the C++ notion of overloading --- a mechanism
that only takes number and type of arguments into account.

As an example, here's one common way of simulating overloading with
Python. We'll dispatch to functions that follow a certain naming
convention based on the class name of the argument:

def foo(arg):
try:
subfunc = eval("foo_%s" % arg.__class__.__name__)
except:
subfunc = foo_default
return subfunc(arg)

def foo_default(arg):
print "default foo behavior"

def foo_int(arg):
print "argument is an integer"

def foo_str(arg):
print "argument is a string"
foo('hello world')
argument is a string
foo(23) argument is an integer
foo({}) # we didn't implement foo_dict default foo behavior

Jul 18 '05 #8

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

Similar topics

8
by: Matthew Bell | last post by:
Hi, I've got a question about whether there are any issues with directly calling attributes and/or methods of a threaded class instance. I wonder if someone could give me some advice on this. ...
1
by: Maurice | last post by:
Hi, We are implementing some wrappers in C++ according to the Adapter Pattern. The classes and their methods in the Adaptee classes (open-source library) have already the interface that we like,...
166
by: Graham | last post by:
This has to do with class variables and instances variables. Given the following: <code> class _class: var = 0 #rest of the class
2
by: Vivek Ragunathan | last post by:
Hi Are the members in a static class in C# class synchronized for multiple thread access. If yes, are all static members in a C# class auto synchronized ? Regards Vivek Ragunathan
4
by: Pedro Werneck | last post by:
Hi all I noticed something strange here while explaining decorators to someone. Not any real use code, but I think it's worth mentioning. When I access a class attribute, on a class with a...
6
by: Joseph Geretz | last post by:
I have the following class which I am serializing and passing back and forth between my Web Service application and the client. public class Token : SoapHeader { public string SID; public...
9
by: Steve Richter | last post by:
in a generic class, can I code the class so that I can call a static method of the generic class T? In the ConvertFrom method of the generic TypeConvert class I want to write, I have a call to...
4
by: Travis | last post by:
Is it considered good practice to call a mutator when inside the same class or modify the attribute directly? So if there's a public method SetName() would it be better from say ::Init() to call...
8
by: nickooooola | last post by:
Hello to all I'm about to write a simulator for a microcontroller in python (why python? because I love it!!!) but I have a problem. The registry of this processor are all 8 bit long (and 10...
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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...

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.