函数定义


In [ ]:
a = 3; b = 2;

In [ ]:
v = a if a > b else b
print v

In [ ]:
def max_value(x, y):
    return x if x > y else y
print max_value(a, b)

In [ ]:
# 无return返回none
def example():
    pass

In [ ]:
x = example()
print x,

函数也是对象


In [ ]:
def square(x):
    """
    return square x values
    """
    return x**2

In [ ]:
square

In [ ]:
dir(square)

In [ ]:
#__doc__返回指定函数的文档字符串。
square.__doc__

In [ ]:
# __name__返回函数名字。
square.func_name

In [ ]:
# 返回一个包含默认参数值的元组
square.func_defaults

In [ ]:
# 返回一个包含函数全局变量的字典引用
square.func_globals

In [ ]:
# 返回支持任意函数属性的命名空间。
square.func_dict

In [ ]:
square.func_closure

In [ ]:
map(square, range(10))

In [ ]:
def func_a():
    a = 10
    def func_b():
        b = 10
        print b
    return func_b

x = func_a()
print x

In [ ]:
x()

In [ ]:
func_b()

命名空间


In [ ]:
dir()

In [ ]:
# 举个例子
top_arg = "Namespace : "
def func_top(arg1):
    def func_bottom(arg3):
        arg2= "K2_inner "
        print(top_arg + arg1 + arg2 + arg3)
    arg2 = " K2 "
    func_bottom("K3 ");
 
func_top("K1 ")

作用域


In [ ]:
### 错误Case

In [ ]:
# UnboundLocalError
i=1
def func2():
    i = i + 1
 
func2()

In [ ]:
def func3():
    a = 123
    del a
    print a
func3()

Locals


In [ ]:
def func1(i, str ):
    x = 12345
    print(locals())
 
func1(1 , "first")

Globals


In [ ]:
# 全局 (模块级别)命名空间可以通过 globals() 
# restart Kernel
arg_test = ''
print("the current scope's global variables:")
dictionary=globals()
print dictionary

# '__builtin__'

内置作用域


In [ ]:
import __builtin__
dir(__builtin__)

In [ ]:
import builtins

查找规则-变量的作用域LGEB


In [1]:
v = "G"
def test():
    v = "L"
    print i, "in locals"

In [2]:
test()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-ea594c21b25d> in <module>()
----> 1 test()

<ipython-input-1-8fa0cdaf5336> in test()
      2 def test():
      3     v = "L"
----> 4     print i, "in locals"

NameError: global name 'i' is not defined

In [3]:
print i, 'in global'


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-c85c8781d97b> in <module>()
----> 1 print i, 'in global'

NameError: name 'i' is not defined

In [4]:
a = 1

def foo():
    a = 2
    print a
print a

foo()


1
2

Enclosed


In [5]:
a = 1
def foo():
    a = 2
    def bar():
        print a
    return bar    

func = foo()
func()


2

Global


In [7]:
x = 666 # global variable

def func():
    global x
    x = 111

func()
print x,


666

In [8]:
y, z = 10, 11
def ref_to_globals():
    x2 = y + z

In [10]:
y, z = 10, 11
def ref_to_globals():
    global x2
    x2 = y + z
x2


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-b3c95a17bcc3> in <module>()
      3     global x2
      4     x2 = y + z
----> 5 x2

NameError: name 'x2' is not defined

Enclosed


In [11]:
a = 10
def f1():
    a = 9
    def f2():
        print a
    f2()
f1()


9

函数参数


In [12]:
def f(a):
    a = 0

b = 1
f(b)
print b


1

In [13]:
# 位置匹配
def record(name, age, email):
    record_name = name
    record_age  = age
    record_email= email
record('Joe', 20, 'Joe@email.com')

In [14]:
# 对于动态语言,上例中第二种调用,并没有类型不匹配的问题。只是内容错误而已。由此也引出了关键字匹配
record(20, 'Joe', 'Joe@email.com')

In [15]:
#在上述例子中第二种调用方式之所以会出现问题,原因在于:
#由于采用位置匹配,所以为了保证输入内容正确,调用时,必须知晓参数的位置(或者顺序)。
#采用关键字匹配就不存在这种问题。
"""
可以看到,关键字匹配与位置匹配的最大区别在于:关键字匹配,在调用函数时,加入了实参与形参的对应信息。
这样做的好处在于,调用者只需要知道调用时需要输入的参数名称即可,不用理会其顺序。另外,从语义的角度来看,这种方式在表达上也更加清晰,因为调用时,十分清楚的写明了:
age = 20,name = 'Joe',email = 'Joe@email.com',
程序的可读性非常高。
"""
record(name = 'Joe', age = 20, email = 'Joe@email.com')
record(age = 20, name = 'Joe', email = 'Joe@email.com')

默认值


In [17]:
def record(name, age, email="xxx@email.com"):
    print name, age, email

In [18]:
record('Joe', 20, 'Joe@gmail.com')


Joe 20 Joe@gmail.com

In [19]:
record('Joe', 20)


Joe 20 xxx@email.com

In [ ]:
# 只提供非缺省位置参数值。在本例中,缺省参数取默认值:

In [20]:
def show_args(arg, def_arg=1, def_arg2=2):
      return "arg={}, def_arg={}, def_arg2={}".format(arg, def_arg, def_arg2)

show_args("tranquility")


Out[20]:
'arg=tranquility, def_arg=1, def_arg2=2'

In [21]:
# 用提供的值覆盖一些默认的参数值,包括非缺省位置参数:
show_args("tranquility", "to Houston")


Out[21]:
'arg=tranquility, def_arg=to Houston, def_arg2=2'

In [22]:
# 为所有参数提供值,可以用这些值覆盖默认参数值
show_args("tranquility", "to Houston", "the eagle has landed")


Out[22]:
'arg=tranquility, def_arg=to Houston, def_arg2=the eagle has landed'

In [23]:
# special case
def show_args_using_mutable_defaults(arg, def_arg=[]):
      def_arg.append("Hello World")
      return "arg={}, def_arg={}".format(arg, def_arg)
show_args_using_mutable_defaults('1')
show_args_using_mutable_defaults('2')


Out[23]:
"arg=2, def_arg=['Hello World', 'Hello World']"

关键字参数


In [24]:
def show_args(arg, def_arg=1):
    return "arg={}, def_arg={}".format(arg, def_arg)

In [25]:
show_args(arg="test", def_arg=3)


Out[25]:
'arg=test, def_arg=3'

In [26]:
show_args('test')


Out[26]:
'arg=test, def_arg=1'

In [27]:
show_args(arg="test")


Out[27]:
'arg=test, def_arg=1'

In [28]:
show_args("test", 3)


Out[28]:
'arg=test, def_arg=3'

In [29]:
# 在函数调用中,关键字参数不得早于非关键字参数
show_args(def_arg=4)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-29-8766e8bf351c> in <module>()
      1 # 在函数调用中,关键字参数不得早于非关键字参数
----> 2 show_args(def_arg=4)

TypeError: show_args() takes at least 1 argument (1 given)

In [30]:
# 函数不能为一个参数提供重复值,所以下面的调用方法是非法的
show_args("test", arg="testing")


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-f0cd5ebe5edb> in <module>()
      1 # 函数不能为一个参数提供重复值,所以下面的调用方法是非法的
----> 2 show_args("test", arg="testing")

TypeError: show_args() got multiple values for keyword argument 'arg'

In [31]:
# 调换了参数顺序的写法
show_args(def_arg="testing", arg="test")


Out[31]:
'arg=test, def_arg=testing'

任意的参数列表


In [32]:
def show_multiple_items(line, separator, *args): 
    return "line:{} is {}".format(line, separator.join(args))

In [33]:
show_multiple_items("start", ",", "1","2","3")


Out[33]:
'line:start is 1,2,3'

解包函数参数


In [34]:
def print_args(*args):
    print ','.join(args)
    
in_args = ["1","2","3"]
print_args(*in_args)


1,2,3

In [35]:
def print_kwargs(arg1, arg2, arg3):
    print arg1, arg2, arg3,

in_kwargs = {'arg1':'k1', 'arg2':'k2', 'arg3':'k3'}
print_kwargs(**in_kwargs)


k1 k2 k3

递归


In [36]:
def factorial(n):
    result = 1
    for i in range(2, n+1):
        result *= i
    return result

In [37]:
factorial(5)


Out[37]:
120

In [38]:
def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n - 1)

In [40]:
factorial(5)


Out[40]:
120

In [41]:
factorial(1000)


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-41-525c41f5ce00> in <module>()
----> 1 factorial(1000)

<ipython-input-38-01a0c28abfa0> in factorial(n)
      3         return 1
      4     else:
----> 5         return n * factorial(n - 1)

... last 1 frames repeated, from the frame below ...

<ipython-input-38-01a0c28abfa0> in factorial(n)
      3         return 1
      4     else:
----> 5         return n * factorial(n - 1)

RuntimeError: maximum recursion depth exceeded

lambda


In [42]:
import math
def square_root(x): return math.sqrt(x)
print square_root(4)


2.0

In [43]:
import math
square_root = lambda x: math.sqrt(x)
print square_root(4)


2.0

嵌套lambda


In [44]:
def action(x):
    return lambda y: x+y

act = action(99)
act(2)


Out[44]:
101

In [45]:
action = (lambda x: (lambda y: x+y))
act = action(99)
act(3)


Out[45]:
102

函数编程


In [47]:
def f1(x):
    return x*2
def f2(x):
    if x!=2:
        return x
def f3(x, y):
    return x + y

In [48]:
r_f1 = map(f1, [1, 2, 3])
print r_f1


[2, 4, 6]

In [49]:
r_f2 = filter(f2, r_f1)
print r_f2


[4, 6]

In [50]:
r_f3 = reduce(f3, r_f2)
print r_f3


10

In [ ]: