473,387 Members | 1,481 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,387 software developers and data experts.

basic language question

Once in a while, I get bitten by the fact, that mutating list methods such
as 'append' or 'extend' return None instead of the (mutated) list itself.
Is there a compelling reason for that? I googled around, but didn't find
anything about this.
Thanks

Stephan
Jul 18 '05 #1
11 1328
Stephan Diehl wrote:
Once in a while, I get bitten by the fact, that mutating list methods
such as 'append' or 'extend' return None instead of the (mutated)
list itself. Is there a compelling reason for that? I googled around,
but didn't find anything about this.
Thanks

Stephan


The reasons described for sort ()
<http://www.python.org/doc/faq/genera...ort-return-the
-sorted-list> also apply to append and extend.

Daniel

Jul 18 '05 #2
Daniel Dittmar wrote:
Stephan Diehl wrote:
Once in a while, I get bitten by the fact, that mutating list methods
such as 'append' or 'extend' return None instead of the (mutated)
list itself. Is there a compelling reason for that? I googled around,
but didn't find anything about this.
Thanks

Stephan
The reasons described for sort ()

<http://www.python.org/doc/faq/genera...ort-return-the -sorted-list> also apply to append and extend.
Thanks for the link. I don't find the given reason really compelling,
though. (but that's mine, not your problem)

Daniel


Stephan

Jul 18 '05 #3

"Stephan Diehl" <st***********@gmx.net> wrote in message
news:bj*************@news.t-online.com...
Once in a while, I get bitten by the fact, that mutating list methods such as 'append' or 'extend' return None instead of the (mutated) list itself. Is there a compelling reason for that? I googled around, but didn't find anything about this.


Some people, including GvR, think in-place mutators should not return
anything to distinguish them from methods which return a new object
and leave original untouched. One argument, I presume based on some
experience, is that if both types of method look the same, people will
forget difference, leading to obscure bugs. Others, confident in
their ability to remember and not make mistakes, want mutated object
returned so they chain methods togethers. While Python is generally a
consenting-adults language, this is one place where Guido opted for
the supposedly 'safer' choice.

'Returners' could wrap no-return mutators with functions or
derived-class methods that do return the object, but I have never seen
anyone post a complete module that does so for, say, all list
mutators.

Terry J. Reedy
Jul 18 '05 #4
Terry Reedy wrote:

"Stephan Diehl" <st***********@gmx.net> wrote in message
news:bj*************@news.t-online.com...
Once in a while, I get bitten by the fact, that mutating list methods such
as 'append' or 'extend' return None instead of the (mutated) list

itself.


[...]

'Returners' could wrap no-return mutators with functions or
derived-class methods that do return the object, but I have never seen
anyone post a complete module that does so for, say, all list
mutators.
That's actually a nice idea. I might just do that.
Terry J. Reedy


Stephan

Jul 18 '05 #5

"Stephan Diehl" <st***********@gmx.net> schrieb im Newsbeitrag
news:bj*************@news.t-online.com...
Once in a while, I get bitten by the fact, that mutating list methods such
as 'append' or 'extend' return None instead of the (mutated) list itself.
Is there a compelling reason for that? I googled around, but didn't find
anything about this.


There is a very old religious law saying: Thou shalt not cause side effects
by a function.
There is some wisdom in it but it is easily forgotten with languages which
do not differ between functions and routines.

Kindly
Michael P
Jul 18 '05 #6

"Michael Peuser" <mp*****@web.de> wrote in message
news:bj*************@news.t-online.com...

"Stephan Diehl" <st***********@gmx.net> schrieb im Newsbeitrag
news:bj*************@news.t-online.com...
Once in a while, I get bitten by the fact, that mutating list methods such as 'append' or 'extend' return None instead of the (mutated) list itself. Is there a compelling reason for that? I googled around, but didn't find
anything about this.
There is a very old religious law saying: Thou shalt not cause side

effects by a function.
There is some wisdom in it but it is easily forgotten with languages which
do not differ between functions and routines.
Like most "religious laws," it's a rule that has a multitude of exceptions.
You can't do I/O without having side effects, something that the designers
of functional languages have learned, sometimes the hard way.

As far as I'm concerned, this is one of those things that Ruby did
right. By convention, methods that modify the object as a side effect
have names that end with an "!" (exclamation point.) Ruby usually supplies
two methods in such cases, one that modifies the object, and one that
creates a copy and then modifies the copy. Both methods return the
modified or new object.

It obeys the Principle of Least Surprise because if you forget the
"!", you get the slow version that does a copy and leaves the original
intact.

Nice as the solution is, it's impossible to import it into Python
cleanly without introducing catastrophic backward incomaptibilities.

John Roth
Kindly
Michael P

Jul 18 '05 #7

"John Roth" <ne********@jhrothjr.com>
"Michael Peuser" <mp*****@web.de>
There is a very old religious law saying: Thou shalt not cause side
effects by a function.
There is some wisdom in it but it is easily forgotten with languages which do not differ between functions and routines.


Like most "religious laws," it's a rule that has a multitude of

exceptions. You can't do I/O without having side effects, something that the designers
of functional languages have learned, sometimes the hard way.


Stream I/O can never be done right in functional languages. The only
solution is to use something like memory mapped files (which I do more and
more ...)

But look at this mess:
twolines=f.readline()+f.readline()
There are solutions in some languages with _routines_ and
_call-by-reference_ but it it is generally very clumpy.

On the other there is a growing popularity of generators and iterators which
by concept are *heretic*

Kindly
Michael P

Jul 18 '05 #8
Stephan Diehl wrote:
Terry Reedy wrote:

"Stephan Diehl" <st***********@gmx.net> wrote in message
news:bj*************@news.t-online.com...
Once in a while, I get bitten by the fact, that mutating list

methods such
as 'append' or 'extend' return None instead of the (mutated) list

itself.


[...]

'Returners' could wrap no-return mutators with functions or
derived-class methods that do return the object, but I have never seen
anyone post a complete module that does so for, say, all list
mutators.


That's actually a nice idea. I might just do that.


o.k., the following short code would give you a list class, that returns
'self' when invoking any of the mutating methods.
The solution involves a metaclass and I wouldn't consider this code more as
an example than an industrial strength solution (for example, at the
moment, you couldn't overload any of these methods)
------------------------------------------------------------------
def wrapedmeth(classname,meth):
def _meth(self,*argl,**argd):
getattr(super(globals()[classname],self),meth)(*argl,**argd)
return self

return _meth

class ReturnMeta(type):
def __new__(cls,classname,bases,classdict):
wrap = classdict.get('return_self_super_methods')
if wrap is not None:
for method in wrap:
classdict[method] = wrapedmeth(classname,meth)
return super(ReturnMeta,cls).__new__(cls,classname,bases, classdict)

class mylist(list):
__metaclass__ = ReturnMeta
return_self_super_methods = ['append',
'extend',
'insert',
'remove',
'reverse',
'sort']
if __name__ == '__main__':
print 'l = [1,2]'
print 'mylist: print l.append(3)'
l = mylist([1,2])
print l.append(3)
print 'list: print l.append(3)'
l = [1,2]
print l.append(3)
------------------------------------------------------------------------------

have fun

Stephan
Jul 18 '05 #9
Stephan Diehl <st***********@gmx.net> writes:
Stephan Diehl wrote:
Terry Reedy wrote:
'Returners' could wrap no-return mutators with functions or
derived-class methods that do return the object, but I have never seen
anyone post a complete module that does so for, say, all list
mutators.
That's actually a nice idea. I might just do that.


o.k., the following short code would give you a list class, that returns
'self' when invoking any of the mutating methods.


OK, here's a variaton on the theme, just wraps the object in-place in
a way which makes it return self. This way you can get the desired
effect on any object you get, without pre-meditation, so you can still
fit the call chain on one line (wasn't that the point?)
The solution involves a metaclass
Mine avoids them altogether.
and I wouldn't consider this code more as an example than an
industrial strength solution


Ditto.
class returner:

def __init__(self, object):
self.object = object

def __getattr__(self, name):
def proxy(*args, **kwds):
getattr(self.object, name)(*args, **kwds)
return self.object
return proxy

lst = [1,2,3]
print lst.append(4) # Here you get None
print returner(lst).append(5) # Here you get the modified list.
Jul 18 '05 #10
Jacek Generowicz <ja**************@cern.ch> writes:
OK, here's a variaton on the theme, just wraps the object in-place in
a way which makes it return self.
I meant "makes any calls to methods return the original object in its
new state."
This way you can get the desired effect on any object you get,
without pre-meditation, so you can still fit the call chain on one
line (wasn't that the point?)


Of course, the chaining should work in Stephan's example too.
Jul 18 '05 #11
Terry Reedy wrote:
...
'Returners' could wrap no-return mutators with functions or
derived-class methods that do return the object, but I have never seen
anyone post a complete module that does so for, say, all list
mutators.


What about...:

def wrapReturning(func):
def returningWrapper(*args, **kwds):
func(*args, **kwds)
return args[0]
return returningWrapper
class metaReturner(type):
''' simplified metaReturner: deal with single inheritance only '''

def __new__(mcl, className, classBases, classDict):

# get the "real" base class, then wrap its mutators
for base in classBases:
if not isinstance(base, metaReturner):
for mutator in classDict['__mutators__']:
classDict[mutator] = wrapReturning(getattr(base,
mutator))
break

# delegate the rest to built-in 'type'
return type.__new__(mcl, className, classBases, classDict)

class Returner: __metaclass__ = metaReturner
# example usage

class returnerlist(Returner, list):
__mutators__ = 'sort reverse append extend insert'.split()

print returnerlist('hello').extend('ciao').sort().revers e()
Alex

Jul 18 '05 #12

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

Similar topics

9
by: abisofile | last post by:
hi I'm new to programming.I've try a little BASIC so I want ask since Python is also interpreted lang if it's similar to BASIC.
9
by: Malcolm | last post by:
After some days' hard work I am now the proud possessor of an ANSI C BASIC interpreter. The question is, how is it most useful? At the moment I have a function int basic(const char *script,...
4
by: Ramesh | last post by:
hi, Let me ask some basic questions. Can anybody explain me about the following questions: 1. When we have to create sn key? Whenever we compiled Component we have to create or it is a one time...
25
by: Jhon | last post by:
Hi every one, I got very basic question, here i go: Say i have 11001 11010 bits which are infact 10 bits. Now i want to address every bit so if it is zero i would add one and if it is one...
18
by: Ann Scharpf via AccessMonster.com | last post by:
I am not sure which would be the best place to post this question, so I'm posing it here with Access general questions. I have reached the point many times in Word and in Access where my ignorance...
97
by: Master Programmer | last post by:
An friend insider told me that VB is to be killled off within 18 months. I guess this makes sence now that C# is here. I believe it and am actualy surprised they ever even included it in VS 2003 in...
6
by: j2ee.singh | last post by:
Hi, I'm looking to buy a new laptop primarily to learn & practice .NET and C#. My Question is: Is there any requirement for .NET and C# in terms of the following Operating Systems: -...
2
by: Dave Dean | last post by:
Hi all, I'm just starting out in sockets/network programming, and I have a very basic question...what are the 'security' implications of opening up a socket? For example, suppose I've written a...
4
by: Chris Asaipillai | last post by:
Hi there My compay has a number of Visual Basic 6 applications which are front endeed onto either SQL Server or Microsoft Access databases. Now we are in process of planning to re-write these...
14
by: MartinRinehart | last post by:
Working on parser for my language, I see that all classes (Token, Production, Statement, ...) have one thing in common. They all maintain start and stop positions in the source text. So it seems...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
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,...

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.