473,698 Members | 2,602 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why are functions atomic?

Why are functions atomic? (I.e. they are not copied.)

For example, I would like to make a copy of a function so I can change
the default values:
>>from copy import copy
f = lambda x: x
f.func_defaul ts = (1,)
g = copy(f)
g.func_defaul ts = (2,)
f(),g()
(2, 2)

I would like the following behaviour:
>>f(),g()
(1,2)

I know I could use a 'functor' defining __call__ and using member
variables, but this is more complicated and quite a bit slower. (I
also know that I can use new.function to create a new copy, but I
would like to know the rational behind the decision to make functions
atomic before I shoot myself in the foot;-)

Thanks,
Michael.

May 1 '07
31 1773
A bit more info, but still no clear picture about why functions are
mutable but have immutable copy symantics. There are arguments why
functions should be immutable, but the decision was to make user-
defined functions mutable. My question is still: why the present
ummutable copy symantics?

http://www.python.org/dev/peps/pep-0232/

May 2 '07 #11
On Tue, 2007-05-01 at 17:28 -0700, Michael wrote:
A bit more info, but still no clear picture about why functions are
mutable but have immutable copy symantics. There are arguments why
functions should be immutable, but the decision was to make user-
defined functions mutable. My question is still: why the present
ummutable copy symantics?
One could make a case that this is a bug, a leftover from when functions
were mostly immutable. However, one can also make a case that correcting
this bug is not worth the effort. Your use case appears to be that you
want to make multiple copies of the same function, and those copies
should be almost, but not quite, the same.

The Pythonic solution is to produce the copies by a factory function
along these lines:
>>def powerfactory(ex ponent):
.... def inner(x):
.... return x**exponent
.... return inner
....
>>square = powerfactory(2)
cube = powerfactory(3)
square(2)
4
>>square(3)
9
>>cube(2)
8
>>cube(3)
27

This approach makes copying functions unnecessary, and as you have
pointed out yourself, if you find yourself needing to make a copy of an
existing function you can work around the unexpected copy semantics with
new.function.

-Carsten
May 2 '07 #12
Michael schrieb:
A bit more info, but still no clear picture about why functions are
mutable but have immutable copy symantics. There are arguments why
functions should be immutable, but the decision was to make user-
defined functions mutable. My question is still: why the present
ummutable copy symantics?
The answer is really really simple. The implementation of copy predates
mutability. When the copy code was written, functions *were* immutable.
When functions became mutable, the copy code was not changed, and
nobody noticed or complained.

Regards,
Martin
May 2 '07 #13
Your use case appears to be that you
want to make multiple copies of the same function, and those copies
should be almost, but not quite, the same.

The Pythonic solution is to produce the copies by a factory function...
>def powerfactory(ex ponent):
... def inner(x):
... return x**exponent
... return inner
Is there a reason for using the closure here? Using function defaults
seems to give better performance:
>>def powerfactory(ex ponent):
.... def inner(x,exponen t=exponent):
.... return x**exponent
.... return inner

This is definitely one viable solution and is essentially what I had
in mind, but I did not want to have to carry the generator arround
with me: Instead, I wanted to use it once as a decorator and then
carry only the function around.
>>@declare_opti ons(first_optio n='opt1')
def f(x,opt1,opt2,o pt3):
.... return x*(opt1+opt2*op t3)
>>f.set_options (opt1=1,opt2=2, opt3=3)
f(1)
7
>>from copy import copy
g = copy(f)
g.set_options (opt1=4,opt2=5, opt3=6)
f(1)
7
>>g(1)
34

The decorator declare_options behaves like the generator above, but
adds some methods (set_options) etc. to allow me to manipulate the
options without generating a new function each time.

I have functions with many options that may be called in the core of
loops, and found that the most efficient solution was to provide all
of the options through func_defaults.
>>def f(x,opt1,opt2,o pt3):
.... return x*(opt1 + opt2*opt3)

The cleanest (and fastest) solution I found was to set the options in
the defaults:
>>f.func_defaul ts = (1,2,3)
Then f can be passed to the inner loops and f(x) is very quick.

Other options include using lists and dict's:
>>opt = (1,2,3)
f(1,*opt)
7

but then I have to pass f and opt around. This also appears to be
somewhat slower than the defaults method. Dictionaries have the
advantage of associating the names with the values
>>opt = {'opt1':1, 'opt2':2, 'opt3':3}
f(1,**opt)
7

but this is much slower. Wrapping the function with a generator as
you suggest also works and packages everything together, but again
suffers in performance. It also complicates my code.

The result of my declare_options decorator is that the result is a
regular function, complete with docstring etc. but with added
annotations that allow the options to be set. In addition, the
performance optimal. I though this was a very clean solution until I
realized that I could not make copies of the functions to allow for
different option values with the usual python copy symantics (for
example, a __copy__ method is ignored). I can easily get around this
by adding a custom copy() method, but wondered if there was anything
inherently dangerous with this approach that would justify the added
complications of more complicated wrappings and the performance hit.

Pickling is an obvious issue, but it seems like there is nothing wrong
with the copy semantics and that the limitations are artificial and
out of place. (It is also easily fixed: if the object has a __copy__
method, use it. Truely immutable objects will never have one. There
may be subtle issues here, but I don't know what they are.)

Thanks for all of the suggestions,
Michael.

May 2 '07 #14
Martin v. Löwis wrote:
Michael schrieb:
>>A bit more info, but still no clear picture about why functions are
mutable but have immutable copy symantics. There are arguments why
functions should be immutable, but the decision was to make user-
defined functions mutable. My question is still: why the present
ummutable copy symantics?


The answer is really really simple. The implementation of copy predates
mutability. When the copy code was written, functions *were* immutable.
When functions became mutable, the copy code was not changed, and
nobody noticed or complained.
That's probably an indication that mutable functions don't
get used all that much. Are there any instances of them in the
standard Python libraries?

John Nagle
May 2 '07 #15
En Wed, 02 May 2007 01:42:17 -0300, Martin v. Löwis <ma****@v.loewi s.de>
escribió:
Michael schrieb:
>A bit more info, but still no clear picture about why functions are
mutable but have immutable copy symantics. There are arguments why
functions should be immutable, but the decision was to make user-
defined functions mutable. My question is still: why the present
ummutable copy symantics?

The answer is really really simple. The implementation of copy predates
mutability. When the copy code was written, functions *were* immutable.
When functions became mutable, the copy code was not changed, and
nobody noticed or complained.
Likely scenario, but not true. Support for copying user functions was
added on 2.5 (see
http://svn.python.org/view/python/tr...38995&r2=42573)
and functions were mutable since a long time ago. On previous versions,
functions could be pickled but not copied.
The same thing happens for classes: they are mutable too, but copy
considers them immutable and returns the same object. This is clearly
stated on the documentation (but the module docstring is still outdated).

--
Gabriel Genellina
May 2 '07 #16
On Tue, 2007-05-01 at 22:21 -0700, Michael wrote:
Is there a reason for using the closure here? Using function defaults
seems to give better performance:[...]
It does? Not as far as I can measure it to any significant degree on my
computer.
This is definitely one viable solution and is essentially what I had
in mind, but I did not want to have to carry the generator arround
with me:
I don't know what you mean by "carry it around." Just put it in a module
and import it where you need it.

An overriding theme in this thread is that you are greatly concerned
with the speed of your solution rather than the structure and
readability of your code. How often is your function going to get called
and how much of a performance benefit are you expecting?

-Carsten
May 2 '07 #17
Michael <mi************ @gmail.comwrote :
Is there a reason for using the closure here? Using function defaults
seems to give better performance:
What measurements show you that...?

brain:~ alex$ cat powi.py
def powerfactory1(e xponent):
def inner(x):
return x**exponent
return inner

def powerfactory2(e xponent):
def inner(x, exponent=expone nt):
return x**exponent
return inner

brain:~ alex$ python -mtimeit -s'import powi; p=powi.powerfac tory1(3)'
'p(27)'
1000000 loops, best of 3: 0.485 usec per loop

brain:~ alex$ python -mtimeit -s'import powi; p=powi.powerfac tory2(3)'
'p(27)'
1000000 loops, best of 3: 0.482 usec per loop
Alex
May 2 '07 #18
>The answer is really really simple. The implementation of copy predates
>mutability. When the copy code was written, functions *were* immutable.
When functions became mutable, the copy code was not changed, and
nobody noticed or complained.

That's probably an indication that mutable functions don't
get used all that much. Are there any instances of them in the
standard Python libraries?
All user-defined functions are mutable. To me, this issue is rather that
copying of functions isn't used all that much.

In addition, it is certainly true that functions are rarely modified,
even though all of them are mutable. See this for an example

pydef foo():pass
....
pyfoo
<function foo at 0xb7db5f44>
pyfoo.__name__= 'bar'
pyfoo
<function bar at 0xb7db5f44>
pyfoo.value
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'function' object has no attribute 'value'
pyfoo.value=100
pyfoo.value
100

Regards,
Martin
May 2 '07 #19
>The answer is really really simple. The implementation of copy predates
>mutability. When the copy code was written, functions *were* immutable.
When functions became mutable, the copy code was not changed, and
nobody noticed or complained.

Likely scenario, but not true.
Interesting. I (clearly) missed that part of the defaultdict discussion
(that was a long thread).

Regards,
Martin
May 2 '07 #20

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

Similar topics

99
5892
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 important changes, so in this thread I would like to focus on that issue alone. I have edited the Proposed Syntax example below to take out the changes unecessary to this discussion. I left in the change of "instance variable" syntax (...
8
3572
by: Glenn Kasten | last post by:
I am wondering which operations in Python are guaranteed to be atomic in the presence of multi-threading. In particular, are assignment and reading of a dictionary entry atomic? For example, initially: dictionary = {} dictionary = old_value Then thread 1 does: v = dictionary And thread 2 does:
42
3348
by: Shayan | last post by:
Is there a boolean flag that can be set atomically without needing to wrap it in a mutex? This flag will be checked constantly by multiple threads so I don't really want to deal with the overhead of mutexes or semaphores. Thanks. Shayan
5
23679
by: Pegboy | last post by:
What does it mean to make a function atomic? Something I read on it wasn't very clear, but made me think that I needed to disable interrupts for that function. Whether that's the case or not, how would I make the following function atomic? int Test; int GetTestValue( void ) {
28
7386
by: robert | last post by:
In very rare cases a program crashes (hard to reproduce) : * several threads work on an object tree with dict's etc. in it. Items are added, deleted, iteration over .keys() ... ). The threads are "good" in such terms, that this core data structure is changed only by atomic operations, so that the data structure is always consistent regarding the application. Only the change-operations on the dicts and lists itself seem to cause problems...
6
6247
by: blackstreetcat | last post by:
consider this code : int i; //gobal var Thread1: i=some value; Thread2: if (i==2) dosomething(); else dosomethingelse();
11
2065
by: japhy | last post by:
Is there a way to read a line (a series of characters ending in a newline) from a file (either by descriptor or stream) atomically, without buffering additional contents of the file?
0
1929
by: yogeeswar | last post by:
Hi All I wrote SP with number of delete commands in an atomic block.And there is a possibility of deleting records from parent table before child table so I wrote a handler to handle the exception.in that handler I am using the ROLLBACK to rollback all the records which were deleted if any exception occurs. THE PROBLEM IS: It is working fine, if the deleting records size is small.but if i tried to delete thousands of records(lorge size)...
2
2933
by: Freedom fighter | last post by:
Hello, Is a singleton class the same as an atomic class? I know that a singleton class can only be instantiated once, but does that concept apply to an atomic class? Thank you.
0
8680
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
9169
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...
0
9030
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8899
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
7738
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6528
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5861
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();...
2
2335
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
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.