This question already has answers here:
nargout in Python
(6 answers)
Closed 7 years ago.
In Python, do functions know how many outputs are requested? For instance, could I have a function that normally returns one output, but if two outputs are requested, it does an additional calculation and returns that too?
Or is this not the standard way to do it? In this case, it would be nice to avoid an extra function argument that says to provide a second input. But I'm interested in learning the standard way to do this.
The real and easy answer is: No.
Python functions/methods does not know about how many outputs are requested, as unpacking of a returned tuple happens after the function call.
What's quite a best practice to do though is to use underscore (_) as a placeholder for unused args that are returned from functions when they're not needed, example:
def f():
return 1, 2, 3
a, b, c = f() # if you want to use all
a, _, _ = f() # use only first element in the returned tuple, 'a'
_, b, _ = f() # use only 'b'
For example, when using underscore (_) pylint will suppress any unused argument warnings.
Python functions always return exactly 1 value.
In this case:
def myfunc():
return
that value is None. In this case:
def myfunc():
return 1, 2, 3
that value is the tuple (1, 2, 3).
So there is nothing for the function to know, really.
As for returning different outputs controlled by parameters, I'm always on the fence about that. It would depend on the actual use case. For a public API that is used by others, it is probably best to provide two separate functions with different return types, that call private code that does take the parameter.
Related
This question already has answers here:
What is the difference between a "function" and a "procedure"?
(18 answers)
Closed 1 year ago.
What the difference for function and Procedure in algorithm ??and how is it defined in python?
please,help me, I am a beginner in programming
In some languages, there is an explicit difference between the two. And the difference is not necessarily the same in all languages where such a difference exists.
In general, when such a distinction exists, it is implied that the function is 'pure', i.e. it always responds with the same output for the same input, and does not alter the state of the surrounding program. Whereas, a procedure, is more to be thought of as a list of commands, which may or may not take parameters, and operates on the existing space, possibly modifying it as a result.
In python there is no such distinction between 'function' and 'procedure', therefore the two can probably be used interchangeably, although presumably the term 'function' would be preferred.
Basically a function is something that calculates or executes a certain task (add a to b), while a procedure is a set of operations you perform in a certain order or depend on each other.
A function takes arguments and returns a value while a procedure does not return values it just performs a set of instructions.
In python they are both declared the same way using the def keyword and you either end it with a return statement if it's a function or not if it's a procedure
Here is an example of both :
function :
def add(a,b):
return a + b
procedure :
def printFullname(firstname,lastname):
print(firstname + ' ' + lastname)
This question already has answers here:
Function chaining in Python
(6 answers)
Closed 6 years ago.
I am calculating a sum using lambda like this:
def my_func(*args):
return reduce((lambda x, y: x + y), args)
my_func(1,2,3,4)
and its output is 10.
But I want a lambda function that takes random arguments and sums all of them. Suppose this is a lambda function:
add = lambda *args://code for adding all of args
someone should be able to call the add function as:
add(5)(10) # it should output 15
add(1)(15)(20)(4) # it should output 40
That is, one should be able to supply arbitrary
number of parenthesis.
Is this possible in Python?
This is not possible with lambda, but it is definitely possible to do this is Python.
To achieve this behaviour you can subclass int and override its __call__ method to return a new instance of the same class with updated value each time:
class Add(int):
def __call__(self, val):
return type(self)(self + val)
Demo:
>>> Add(5)(10)
15
>>> Add(5)(10)(15)
30
>>> Add(5)
5
# Can be used to perform other arithmetic operations as well
>>> Add(5)(10)(15) * 100
3000
If you want to support floats as well then subclass from float instead of int.
The sort of "currying" you're looking for is not possible.
Imagine that add(5)(10) is 15. In that case, add(5)(10)(20) needs to be equivalent to 15(20). But 15 is not callable, and in particular is not the same thing as the "add 15" operation.
You can certainly say lambda *args: sum(args), but you would need to pass that its arguments in the usual way: add(5,10,20,93)
[EDITED to add:] There are languages in which functions with multiple arguments are handled in this sort of way; Haskell, for instance. But those are functions with a fixed number of multiple arguments, and the whole advantage of doing it that way is that if e.g. add 3 4 is 7 then add 3 is a function that adds 3 to things -- which is exactly the behaviour you're wanting not to get, if you want something like this to take a variable number of arguments.
For a function of fixed arity you can get Haskell-ish behaviour, though the syntax doesn't work so nicely in Python, just by nesting lambdas: after add = lambda x: lambda y: x+y you can say add(3)(4) and get 7, or you can say add(3) and get a function that adds 3 to things.
[EDITED again to add:] As Ashwini Chaudhary's ingenious answer shows, you actually can kinda do what you want by arranging for add(5)(10) to be not the actual integer 15 but another object that very closely resembles 15 (and will just get displayed as 15 in most contexts). For me, this is firmly in the category of "neat tricks you should know about but never ever actually do", but if you have an application that really needs this sort of behaviour, that's one way to do it.
(Why shouldn't you do this sort of thing? Mostly because it's brittle and liable to produce unexpected results in edge cases. For instance, what happens if you ask for add(5)(10.5)? That will fail with A.C.'s approach; PM 2Ring's approach will cope OK with that but has different problems; e.g., add(2)(3)==5 will be False. The other reason to avoid this sort of thing is because it's ingenious and rather obscure, and therefore liable to confuse other people reading your code. How much this matters depends on who else will be reading your code. I should add for the avoidance of doubt that I'm quite sure A.C. and PM2R are well aware of this, and that I think their answers are very clever and elegant; I am not criticizing them but offering a warning about what to do with what they've told you.)
You can kind of do this with a class, but I really wouldn't advise using this "party trick" in real code.
class add(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, arg):
self.arg += arg
return self
def __repr__(self):
return repr(self.arg)
# Test
print(add(1)(15)(20)(4))
output
40
Initially, add(1) creates an add instance, setting its .args attribute to 1. add(1)(15) invokes the .call method, adding 15 to the current value of .args and returning the instance so we can call it again. This same process is repeated for the subsequent calls. Finally, when the instance is passed to print its __repr__ method is invoked, which passes the string representation of .args back to print.
This question already has answers here:
How to print Docstring of python function from inside the function itself?
(8 answers)
Closed 7 years ago.
I have been searching for an answer for a lot of time now. Let's say I wrote a function in python and I made a brief documentation of what this function is doing. Is there any way to print the function's documentation from within main? Or from the function itself?
You can either use help() or print the __doc__. help() prints a more verbose description of an object while __doc__ holds only the documentation string you have defined with triple quotes """ """ in the beginning of your function.
For example, using __doc__ explicitly on the sum built-in function:
print(sum.__doc__)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
Additionally, since Python first compiles an object and during execution evaluates it you can call __doc__ within the function with no problems:
def foo():
"""sample doc"""
print(foo.__doc__)
foo() # prints sample doc
and remember, besides functions, modules and classes have a __doc__ attribute holding their documentation.
Alternatively, using help() for sum:
help(sum)
Will print:
Help on built-in function sum in module builtins:
sum(iterable, start=0, /)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
gives a bit more information, including the docstring.
This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed 6 months ago.
in order to automatically generate parameterized tests, I am trying to add methods to a class in by freezing some parameters of an existing method. Here is the piece of Python 3 code
class A:
def f(self, n):
print(n)
params = range(10)
for i in params:
name = 'f{0}'.format(i)
method = lambda self: A.f(self, i)
setattr(A, name, method)
However, the following lines then produce rather disappointing output
a = A()
a.f0()
prints "9" (instead of "0"). I must be doing something wrong, but I can't see what. Can you help ?
Thanks a lot
Edit: this question is indeed a duplicate. I would like to acknowledge the quality of all comments, which go much deeper than the raw answer.
Try
method = lambda self, i=i: A.f(self, i)
because otherwise when you call the method i's value may have changed
The best way to "freeze" parameters in Python is to use functools.partial. It's roughly equivalent to warwaruk's lambda version, but if you have a function with lots of arguments yet only want to freeze one or two of them (or if you only know certain arguments and don't care about the rest) using partial is more elegant as you only specify the arguments you want to freeze rather than having to repeat the whole function signature in the lambda.
An example for your program:
class A:
def f(self, n):
print(n)
from functools import partial
for i in range(10): # params
setattr(A, 'f{0}'.format(i), partial(A.f, n=i))
Depending on which version of Python 3 you're using, you may not need to include the 0 in the string format placeholder; starting with 3.1, iirc, it should be automatically substituted.
I have a function which returns 3 numbers, e.g.:
def numbers():
return 1,2,3
usually I call this function to receive all three returned numbers e.g.:
a, b, c = numbers()
However, I have one case in which I only need the first returned number.
I tried using:
a, None, None = numbers()
But I receive "SyntaxError: assignment to None".
I know, of course, that I can use the first option I mentioned and then simply not use the "b" and "c" variables. However, this seems like a "waste" of two vars and feels like wrong programming.
a, _, _ = numbers()
is a pythonic way to do this. In Python 3, you could also use:
a, *_ = numbers()
To clarify _ is a normal variable name in Python, except it is conventionally used to refer to non-important variables.
Another way is of course a=numbers()[0], if you do not want to declare another variable. Having said this though, I generally use _ myself.
The way I do it:
a = numbers()[0]
Seeing as the type returned is a tuple, you can access it via index.
This solution keeps you from having to declare unused/meaningless variables such as "_". Most people don't mind unused variables, however my pylint is setup to warn me of such things as they could indicate potentially unused code, etc.