- In python, function is the first-class object. It's can be used as an argument.
- Function can be used as a return value.
return func1
: reference tofunc1
.return func1()
: results of evaluatingfunc()
.
- Should we check the argument/input?: No! The responsibility is on the caller! Your function should be well-documented, that's it! (ref)
If a function doesn't return any value, it returns
None
.1# without arguments
2def func_name():
3 pass
1# with arguments
2def func_name(<args>):
3 pass
1# return
2def func_name(<args>):
3 return <some_thing>
1# call a function
2func_name(<args>)
1def sum_and_div(num1, num2):
2 sum_nums = num1 + num2
3 div_nums = num1 / num2
4 return sum_nums, div_nums # multiple returns
5
6sum, div = sum_and_div(18, 9)
7print(sum, div)
1# output
227 2.0
The
*args
will give you all function parameters as a tuple: (ref)1def foo(*args):
2 print(args)
3 for a in args:
4 print(a)
5
6foo(1)
7foo(2, 3, 4)
1# output
2(1,)
31
4(2, 3, 4)
52
63
74
1def foo(rarg1, rarg2):
2 print(rarg1, rarg2)
3
4lst = [1, 2]
5foo(*lst)
6tpl = (3, 4)
7foo(*tpl)
1# output
21 2
33 4
4
If you wanna use "keywords arguments", use
**args
:1def kwfunc(**kwargs):
2 print(type(kwargs))
3 print(kwargs)
4
5kwfunc()
6kwfunc(kw1="thi", kw2="dinh")
1# output
2<class 'dict'>
3{}
4<class 'dict'>
5{'kw1': 'thi', 'kw2': 'dinh'}
Use a dictionary as an input,
1def kwfunc(**kwargs): # must have **
2 print(kwargs)
3
4kwargs = {'kw1': "thi", 'kw2': "dinh"}
5kwfunc(**kwargs) # must have **
6
1# output
2{'kw1': 'thi', 'kw2': 'dinh'}
1def kwfunc(kw1="john", kw2="doe"):
2 print(kw1, kw2)
3
4kwargs = {'kw1': "thi", 'kw2': "dinh"}
5
6kwfunc()
7kwfunc(kwargs) # goes to kw1
8kwfunc(**kwargs) # goes to both kw1 & kw2
9
1# output
2john doe
3{'kw1': 'thi', 'kw2': 'dinh'} doe
4thi dinh
Coupling
rargs
, *args
and **kwargs
:- Required positional arguments:
rarg1
,rarg2
, ...
- Optional positional arguments:
args
.
- Optional key-values arguments:
*kwargs
.
1def kwfunc(rarg1=0, rarg2=0, *args, **kwargs):
2 print("required args: ", rarg1, rarg2)
3 if args:
4 print("*args: ", args)
5 if kwargs:
6 print("**kwargs: ", kwargs)
7 print("\\n")
8
9
10kwfunc()
11kwfunc(1, 2)
12kwfunc(3, 4, 5, 6)
13kwfunc(kw1="thi", kw2="dinh")
1# output
2required args: 0 0
3
4required args: 1 2
5
6required args: 3 4
7*args: (5, 6)
8
9required args: 0 0
10**kwargs: {'kw1': 'thi', 'kw2': 'dinh'}
All arguments after
*
must be key-value arguments,1def func(rarg1, rarg2, *, kwarg1, kwarg2):
2 print("required args: ", rarg1, rarg2)
3 print("kwarg*: ", kwarg1, kwarg2)
4
5# func(1, 2, 3, 4) # error!
6func(1, 2, kwarg1=3, kwarg2=4)
1# output
2required args: 1 2
3kwarg*: 3 4
It's convenient but don't use it regularly, use
def
(in 1 line) instead.1x = lambda a : a + 10
2print(x(5))
3
4# you can use this
5def x(a): return a + 10
1# output
215
1# if else with lambda function
2lambda row: 'good' if (row>=80) else ('bad' if row<80 else '')
Something like that,
1if par1 is None:
2 msg = "par1 must be in type `int`"
3 raise TypeError(msg)
You can check other exceptions here.
1def my_decorator(func):
2 def wrapper():
3 print("Before func called.")
4 func()
5 print("After func called.")
6 return wrapper
7
8def say_whee():
9 print("Whee!")
10
11say_whee = my_decorator(say_whee)
12say_whee()
1# output
2Before func called.
3Whee!
4After func called.
In a class (note that, there is no
self
parameter in _deco
),1class test_class():
2
3 def _deco(func):
4 def wrapper(self, name):
5 print('Before func called')
6 func(self, name)
7 print('After func called.')
8 return wrapper
9
10 @_deco
11 def fit(self, name):
12 print('Hello, ', name)
13
14a = test_class()
15a.fit('thi')
1# output
2Before func called
3Hello, thi
4After func called