473,854 Members | 1,637 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to write Smart Python programs?

Raj
Hi,

We just executed a project with Python using TG. The feedback was to
use more python like programming rather than C style code executed in
Python. The feedback is from a Python purist and for some reasons we
cannot solicity his help.

So we'd like to do is to scrub through the codebase and identify places
where the codebase needs improvement, both from styling as well as
design. Is there any website that can provide me with advanced tips
rather than just tutorials coz thats not of much help.

The project involves:
1. A server module that receives messages from a datalogger to populate
a database
2. A DB access module that interfaces with the UI

The technologies we use are TurboGears, SQLAlchemy, CherryPy, Kid
templates.

Any help will be greatly appreciated. If you would like to get involved
in it for $$ (experienced in the tools mentioned above) as well do let
me know. I need help asap as the deadlines are very very short.

Thanks,
Raj.

Oct 11 '06 #1
21 1931
Raj wrote:
Hi,

We just executed a project with Python using TG. The feedback was to
use more python like programming rather than C style code executed in
Python. The feedback is from a Python purist and for some reasons we
cannot solicity his help.

So we'd like to do is to scrub through the codebase and identify places
where the codebase needs improvement, both from styling as well as
design. Is there any website that can provide me with advanced tips
rather than just tutorials coz thats not of much help.
Googling for "python is not java" may be a good start. Also, here are 2
common C-style smells:

1/ using explicit indexing instead of iteration:

C-smell :
for i in range(len(seq)) :
do_something_wi th(seq[i])

Pythonic:
for item in seq:

do_something_wi th(item)
# or if you need the index too:
for i, item in enumerate(seq):
do_something_wi th(i, item)

2/ functions that returns a status code and modify their arguments. The
pythonic way is to have the function return multiple args and raise an
exception if something went wrong
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Oct 11 '06 #2
On 10/11/06, Bruno Desthuilliers <on***@xiludom. growrote:
2/ functions that returns a status code and modify their arguments.
Argument modification for lists with one item is *sometimes* used to
emulate full lexical closure. (or at least that's what the folks on
freenode #python told me)

-- Theerasak
Oct 11 '06 #3
Theerasak Photha wrote:
>2/ functions that returns a status code and modify their arguments.

Argument modification for lists with one item is *sometimes* used to
emulate full lexical closure. (or at least that's what the folks on
freenode #python told me)
sounds like they (or you) are confusing "arguments" with "free
variables", though. here's an example of the latter:

def outer():
var = [value]
def inner():
var[0] = new value
inner()

here's an example of the former:

def func(var):
var[0] = new value
return something else

myvar = [value]
res = func(myvar)

the second example feels rather contrived; if you need to return
multiple values, just return them.

</F>

Oct 11 '06 #4
On 10/11/06, Fredrik Lundh <fr*****@python ware.comwrote:
Theerasak Photha wrote:
>2/ functions that returns a status code and modify their arguments.
Argument modification for lists with one item is *sometimes* used to
emulate full lexical closure. (or at least that's what the folks on
freenode #python told me)

sounds like they (or you) are confusing "arguments" with "free
variables", though. here's an example of the latter:
This is (kind of) what we were talking about:

http://www.c2.com/cgi/wiki?ClosuresT...inalLimitation

-- Theerasak
Oct 11 '06 #5
Googling for "python is not java" may be a good start. Also, here are 2
common C-style smells:
Ok, the first Google result
(http://dirtsimple.org/2004/12/python-is-not-java.html) says this somewhere:

"Getters and setters are evil. Evil, evil, I say! Python objects are not
Java beans. Do not write getters and setters. This is what the
'property' built-in is for. And do not take that to mean that you should
write getters and setters, and then wrap them in 'property'. (1) That
means that until you prove that you need anything more than a simple
attribute access, don't write getters and setters. They are a waste of
CPU time, but more important, they are a waste of programmer time. Not
just for the people writing the code and tests, but for the people who
have to read and understand them as well.

In Java, you have to use getters and setters because using public fields
gives you no opportunity to go back and change your mind later to using
getters and setters. (2) So in Java, you might as well get the chore out
of the way up front. In Python, this is silly, because you can start
with a normal attribute and change your mind at any time, without
affecting any clients of the class. (3) So, don't write getters and
setters."

For the record, I'm coming from Java, but I have some Python experience
already.

Now here's what I don't understand.

What exactly is meant by (1)? The python library reference includes this
as an example:

class C(object):
def __init__(self): self.__x = None
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")

To me this seems contradictory. Why would one not want to do something
that is included in the documentation? Or am I just confused? Does
anybody have an idea how to put me in the right direction?

And what does property mean anyway? The explanation in
http://docs.python.org/lib/built-in-funcs.html is not enough for me. Can
anybody point me to a more detailed documentation about this matter? (At
first sight, the Python tutorial doesn't seem to describe this. At least
it is not stated in the TOC, nor in chapter 9 which describes classes...)

And then, by (2) I believe that what is meant is that once some client
code uses public fields one can't make them private anymore because then
the clients are broke. That's clear to me. But I don't understand (3). I
don't know exactly what they mean. How would one want to change their
mind? In what way? I've been thinking about it some time now, but I'm
still kept in the dark. I would appreciate any explanation.

I'd really like to get this, because when I use a language I want to use
it "correctly" , i.e. in the way it is intended, but right now I feel a
bit lost :-(

I'm not done with 'How To Ask Questions The Smart Way' yet, so please
forgive any violations. (http://catb.org/~esr/faqs/smart-questions.html)

Regards,
antoine
Oct 11 '06 #6
Antoine De Groote <an*****@vo.luw rites:
To me this seems contradictory. Why would one not want to do something
that is included in the documentation? Or am I just confused? Does
anybody have an idea how to put me in the right direction?
The library reference states the technical procedures for doing
various things. That is, it explains how the procedures work. It
doesn't say when to use one procedure or another. It's a technical
reference, not a style guide.
And then, by (2) I believe that what is meant is that once some client
code uses public fields one can't make them private anymore because
then the clients are broke. That's clear to me. But I don't understand
(3). I don't know exactly what they mean. How would one want to change
their mind? In what way? I've been thinking about it some time now,
but I'm still kept in the dark. I would appreciate any explanation.
I think it means the example you cited from the library doc is
inadvisable in practice, and should only be used as a template for
more complicated getters and setters. E.g. if you want the client
to be able to set foo.x to an arbitrary value, don't use a setter,
just say

foo.x = 237

and the attribute value gets set directly. If you want to limit the
value of foo.x to the range 0-100, and make setting to outside the
range clip to that range or raise an exception or something, THEN use
a setter. In Python, you can omit the setter at first (so there's no
restriction), then later decide you want to add the restriction, so
you add the setter. In Java, if you omit the setter at first and then
later want to add it, you have to change all the client calls.
Oct 11 '06 #7
Antoine De Groote <an*****@vo.luw rites:
Ok, the first Google result
(http://dirtsimple.org/2004/12/python-is-not-java.html) says this somewhere:

"Getters and setters are evil. Evil, evil, I say! Python objects are
not Java beans. Do not write getters and setters. This is what the
'property' built-in is for. And do not take that to mean that you
should write getters and setters, and then wrap them in
'property'. (1) That means that until you prove that you need
anything more than a simple attribute access, don't write getters
and setters. They are a waste of CPU time, but more important, they
are a waste of programmer time. Not just for the people writing the
code and tests, but for the people who have to read and understand
them as well. [...]"

What exactly is meant by (1)? The python library reference includes
this as an example:

class C(object):
def __init__(self): self.__x = None
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")

To me this seems contradictory. Why would one not want to do
something that is included in the documentation? Or am I just
confused? Does anybody have an idea how to put me in the right
direction?
Note that, to a user of that class, the fact that it's implemented as
a property is opaque. Thus, changing an attribute from a simple value
object, to a property, can be done as and when needed, without
changing any of the code that uses that class.

So, it's best to always code plain public attributes without getters
and setters in the first instance:
>>class Foo(object):
... def __init__(self):
... self.menu = "spam"
...
>>foo = Foo()
foo.menu
'spam'
>>foo.menu = "sausage"
foo.menu
'sausage'

Because later, when one wants to refactor the implementation of that
attribute without changing the interface, only the implementation
needs to change:
>>class Foo(object):
... def __init__(self):
... self._menu = ["spam", "eggs", "beans"]
... self.current_it em = 0
... def _get_menu(self) :
... return self._menu[self.current_it em]
... def _set_menu(self, value):
... self._menu[self.current_it em] = value
... menu = property(_get_m enu, _set_menu)
...

And the code that uses that attribute can remain the same:
>>foo = Foo()
foo.menu
'spam'
>>foo.menu = "sausage"
foo.menu
'sausage'

Thus, coding getters and setters without a demonstrated need to do so
in a particular case is a waste of effort and an increase in
complexity, with no benefit.
I'm not done with 'How To Ask Questions The Smart Way' yet, so
please forgive any violations.
Your awareness of that document, and your attempt to follow it
sincerely, is much more important.

--
\ "He that would make his own liberty secure must guard even his |
`\ enemy from oppression." -- Thomas Paine |
_o__) |
Ben Finney

Oct 11 '06 #8
Theerasak Photha wrote:
On 10/11/06, Bruno Desthuilliers <on***@xiludom. growrote:
>2/ functions that returns a status code and modify their arguments.

Argument modification for lists with one item is *sometimes* used to
emulate full lexical closure. (or at least that's what the folks on
freenode #python told me)
Yes, but that's another point. What I was talking about (perhaps not
clearly) is mutable arguments used as returned values, ie:

C-smell:

def my_func(res):
bar = foo()
if bar is None:
return 1 # error
else:
res['bar'] = bar
res['baaz'] = "blah"
return 0 # no error

pythonic:

def my_func():
bar = foo()
if bar is None:
raise FooBarError("no bar from foo")
return dict(bar=bar, baaz='blah')
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Oct 11 '06 #9
Antoine De Groote wrote:
>Googling for "python is not java" may be a good start. Also, here are 2
common C-style smells:

Ok, the first Google result
(http://dirtsimple.org/2004/12/python-is-not-java.html) says this
somewhere:

"Getters and setters are evil. Evil, evil, I say! Python objects are not
Java beans. Do not write getters and setters. This is what the
'property' built-in is for. And do not take that to mean that you should
write getters and setters, and then wrap them in 'property'. (1) That
means that until you prove that you need anything more than a simple
attribute access, don't write getters and setters. They are a waste of
CPU time, but more important, they are a waste of programmer time. Not
just for the people writing the code and tests, but for the people who
have to read and understand them as well.

In Java, you have to use getters and setters because using public fields
gives you no opportunity to go back and change your mind later to using
getters and setters. (2) So in Java, you might as well get the chore out
of the way up front. In Python, this is silly, because you can start
with a normal attribute and change your mind at any time, without
affecting any clients of the class. (3) So, don't write getters and
setters."

For the record, I'm coming from Java, but I have some Python experience
already.

Now here's what I don't understand.

What exactly is meant by (1)? The python library reference includes this
as an example:

class C(object):
def __init__(self): self.__x = None
def getx(self): return self._x
def setx(self, value): self._x = value
def delx(self): del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")

To me this seems contradictory. Why would one not want to do something
that is included in the documentation? Or am I just confused? Does
anybody have an idea how to put me in the right direction?
Have you tried running the above snippet in a python shell ?
>>c = C()
c.x = 42
c.x
42

And what does property mean anyway?
See above. A property is a computed attribute : you access it like a
'data' attribute, but it really uses getters/setters. The point here is
that client code doesn't know nor need to know if it's a plain attribute
or a computed one. This let you change implementation (turn a plain
attribute into a computed one) without breaking the API. So the real
thing is not "don't use getters and setters", but "don't bother with
getters and setters, you'll be able to add them transparently if and
when needed".

As a side node, the getters/setters of a property are often either
marked as implementation (the _leading_unders core convention) or deleted
from the class's dict once the property is created or 'masked' one way
or another so they don't pollute the class's namespace.

Also and FWIW, properties are just one possible application of the
descriptor protocol. If you want to grasp Python's object model, I'd
recommand that you read about descriptors and metaclasses.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Oct 11 '06 #10

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

Similar topics

5
2134
by: NEWS | last post by:
Can I install Python on a networked server and have any user run Python programs without having to go through the 9Mb client install? What are my options for distributing Python programs to my users? Thankyou to anyone who can help. Graham
8
1576
by: Darren Dale | last post by:
Is there a place to put python programs so I dont have to refer to the absolute path everytime I want to call them? For example: if I am in /home/me and want to execute: python /home/me/python/export.py temp.dat what could I do so this will work: python export.py temp.dat
20
2310
by: Guy Fawkes | last post by:
Hi, I was wondering if Python programs always need to include the source code with the program itself. I'm asking this because I don't want my program to be open-source and so far all the Python programs I've seen included the source code. Is it possible to make an executable with only bytecode? Thanks in advance!
12
2759
by: Steve Howell | last post by:
I've always thought that the best way to introduce new programmers to Python is to show them small code examples. When you go to the tutorial, though, you have to wade through quite a bit of English before seeing any Python examples. Below is my attempt at generating ten fairly simple, representative Python programs that expose new users
0
9901
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
11024
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10744
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10364
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7077
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5937
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4550
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4150
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3182
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.