python how to define function with optional parameters by square brackets? - python

I often find some functions defined like open(name[, mode[, buffering]]) and I know it means optional parameters.
Python document says it's module-level function. When I try to define a function with this style, it always failed.
For example
def f([a[,b]]): print('123')
does not work.
Can someone tell me what the module-level means and how can I define a function with this style?

Is this what you are looking for?
>>> def abc(a=None,b=None):
... if a is not None: print a
... if b is not None: print b
...
>>> abc("a")
a
>>> abc("a","b")
a
b
>>> abc()
>>>

"if we can define optional parameters using this way(no at present)"
The square bracket notation not python syntax, it is Backus-Naur form - it is a documentation standard only.
A module-level function is a function defined in a module (including __main__) - this is in contrast to a function defined within a class (a method).

Related

pytest - monkeypatch keyword argument default

I'd like to test the default behavior of a function. I have the following:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar(text=DEFAULT_VALUE):
print(text)
# test/test_app.py
import app
def test_app(monkeypatch):
monkeypatch.setattr('app.foo.DEFAULT_VALUE', 'patched')
app.foo.bar()
assert 0
Output is hello; not what I wanted.
One solution is to pass the default value explicitly: app.foo.bar(text=app.foo.DEFAULT_VALUE).
But I find it interesting that this doesn't seem to be an issue when defaulting to the global scope:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar():
print(DEFAULT_VALUE)
Output is patched.
Why does this happen? And is there a better solution than passing the default explicitly?
Function defaults are bound at function definition time.
By the time you are in test code, the module in which the function was defined has already been imported and it is too late to swap out the default by monkeypatching on the module level constant. That name was already resolved.
A workaround is to define the function like this:
def bar(text=None):
if text is None:
text = DEFAULT_VALUE
print(text)
Now the default value is looked up at function call time, which means a monkeypatch on the module level default will still work.
If you don't like to modify the function definition, then you can monkeypatch the function object itself:
monkeypatch.setattr("app.foo.bar.__defaults__", ("test_hello",))
This is because when you import the app module the module get's interpreted when imported so once it is imported into foo the module looks like this:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar(text='hello'):
print(text)
When you call the function the code inside the function get's interpreted which explains why you see the monkey patched DEFAULT_VALUE

What does the # symbol do in iPython/Python [duplicate]

This question already has answers here:
What does the "at" (#) symbol do in Python?
(14 answers)
Closed 9 years ago.
A code that I'm reading uses #batch_transform. What does the # symbol do? Is it ipython specific?
from zipline.transforms import batch_transform
from scipy import stats
#batch_transform
def regression_transform(data):
pep_price = data.price['PEP']
ko_price = data.price['KO']
slope, intercept, _, _, _ = stats.linregress(pep_price, ko_price)
return intercept, slope
The # syntax signals that batch_transform is a Python decorator, read more about it in the wiki, quoting:
A Python decorator is a specific change to the Python syntax that allows us to more conveniently alter functions and methods (and possibly classes in a future version). This supports more readable applications of the DecoratorPattern but also other uses as well
Also take a look at the documentation:
A function definition may be wrapped by one or more decorator expressions. Decorator expressions are evaluated when the function is defined, in the scope that contains the function definition. The result must be a callable, which is invoked with the function object as the only argument. The returned value is bound to the function name instead of the function object. Multiple decorators are applied in nested fashion
It is a decorator. A Python decorator.
Function, method, or class definitions may be preceded by a # special symbol known as a decorator, the purpose of which is to modify the behavior of the definition that follows.
Decorators are denoted with the # symbol and must be placed on a separate line immediately before the corresponding function, method, or class. Here’s an example:
class Foo(object):
#staticmethod
def bar():
pass
Also, you can have multiple decorators:
#span
#foo
def bar():
pass
Here is a good lesson on it. Here is a great thread on it for SO.
any function can be wrapped using a decorator by # symbol
example
def decor(fun):
def wrapper():
print "Before function call"
print fun()
print "Before function call"
return wrapper
#decor
def my_function():
return "Inside Function"
my_function()
## output ##
Before function call
Inside Function
Before function call
[NOTE] even classmethod and staticmethod's are implemented using decorators in python
In your case, there would be function called batch_transform, and you have imported it !

Synthetic functions in python

In python I can create a class without class statement:
MyClass = type('X', (object,), dict(a=1))
Is there a way to create a function without 'def'?
Thats as far as i got...
d={} # func from string
exec'''\
def synthetics(s):
return s*s+1
''' in d
>>> d.keys()
['__builtins__', 'synthetics']
>>> d['synthetics']
<function synthetics at 0x00D09E70>
>>> foo = d['synthetics']
>>> foo(1)
2
Technically, yes, this is possible. The type of a function is, like all other types, a constructor for instances of that type:
FunctionType = type(lambda: 0)
help(FunctionType)
As you can see from the help, you need at minimum code and globals. The former is a compiled bytecode object; the latter is a dictionary.
To make the code object, you can use the code type's constructor:
CodeType = type((lambda: 0).func_code)
help(CodeType)
The help says this is "not for the faint of heart" and that's true. You need to pass bytecode and a bunch of other stuff to this constructor. So the easiest way to get a code object is from another function, or using the compile() function. But it is technically possible to generate code objects completely synthetically if you understand Python bytecode well enough. (I have done this, on a very limited basis, to construct signature-preserving wrapper functions for use in decorators.)
PS -- FunctionType and CodeType are also available via the types module.
There might be a more direct way than the following, but here's a full-blown function without def. First, use a trivial lambda expression to get a function object:
>>> func = lambda: None
Then, compile some source code to get a code object and use that to replace the lambda's code:
>>> func.__code__ = compile("print('Hello, world!')", "<no file>", "exec")
>>> func()
Hello, world!

How to get line number of function (with/without a decorator) in a python module?

I want to get the line number of a python function in the source code.
What i have in runtime is module, class, method objects
Had a look at inspect
inspect.getsourcelines(object)
which also gives line number in result.
I see that for methods with decorators, line no. returned from above inspect function points to the actual decorator's source code rather than desired function's source code.
So any way to workaround this?
(i understand that interpreter does something like wrapping function inside decorator in runtime, but i might be wrong)
There is no easy solution in the general case.
A decorator is a function that given a function returns a function, normally by "wrapping" it in a closure that performs the operation for which the decorator has been designed.
The file and line number information are not however in the function object itself and you cannot "fix" them by copying this information from the wrapped function to the wrapper. That data is instead contained in the code object of the function (available with .func_code), and it is shared among all closures you are going to create.
>>> def bar(x):
... def foo():
... return x
... return foo
...
>>> f1 = bar(1)
>>> f2 = bar(2)
>>> f1()
1
>>> f2()
2
>>> f1.func_code is f2.func_code
True
>>>
The wrapt module solves this problem by allowing you to write decorators which preserve the necessary metadata to find the source of a function as well as perform other introspection. It's like an improved functools.wraps.

Parse Python file and evaluate selected functions

I have a file that contains several python functions, each with some statements.
def func1():
codeX...
def func2():
codeY...
codeX and codeY can be multiple statements. I want to be able to parse the file, find a function by name, then evaluate the code in that function.
With the ast module, I can parse the file, find the FunctionDef objects, and get the list of Stmt objects, but how do I turn this into bytecode that I can pass to eval? Should I use the compile module, or the parser module instead?
Basically, the function defs are just used to create separate blocks of code. I want to be able to grab any block of code given the name and then execute that code in eval (providing my own local/global scope objects). If there is a better way to do this than what I described that would be helpful too.
Thanks
I want to be able to grab any block of code given the name and then execute that code ... (providing my own local/global scope objects).
A naive solution looks like this. This is based on the assumption that the functions don't all depend on global variables.
from file_that_contains_several_python_functions import *
Direction = some_value
func1()
func2()
func3()
That should do exactly what you want.
However, if all of your functions rely on global variables -- a design that calls to mind 1970's-era FORTRAN -- then you have to do something slightly more complex.
from file_that_contains_several_python_functions import *
Direction = some_value
func1( globals() )
func2( globals() )
func3( globals() )
And you have to rewrite all of your global-using functions like this.
def func1( context )
globals().update( context )
# Now you have access to all kinds of global variables
This seems ugly because it is. Functions which rely entirely on global variables are not really the best idea.
Using Python 2.6.4:
text = """
def fun1():
print 'fun1'
def fun2():
print 'fun2'
"""
import ast
tree = ast.parse(text)
# tree.body[0] contains FunctionDef for fun1, tree.body[1] for fun2
wrapped = ast.Interactive(body=[a.body[1]])
code = compile(wrapped, 'yourfile', 'single')
eval(code)
fun2() # prints 'fun2'
Take a look at grammar in ast doc: http://docs.python.org/library/ast.html#abstract-grammar. Top-level statement must be either Module, Interactive or Expression, so you need to wrap function def in one of those.
If you're using Python 2.6 or later, then the compile() function accepts AST objects in addition to source code.
>>> import ast
>>> a = ast.parse("print('hello world')")
>>> x = compile(a, "(none)", "exec")
>>> eval(x)
hello world
These modules have all been rearranged for Python 3.

Categories

Resources