菜单

python函数默认参数作用域

2019年11月3日 - 金沙国际唯一官网

当def函数参数默认值为对象时,例如列表[],字典{}

二、函数

python 在调用时计算默认值

大家都知道python的默认值是在函数定义时计算出来的,
也就是说默认值只会计算一次, 之后函数调用时, 如果参数没有给出,

同一个值会赋值给变量, 这会导致, 如果我们想要一个list默认值,
新手通常这么写:

 

def foo(a=[]):

 a.append(3)

 print a

其实是错误的,两次调用会这样的结果:

 

[3]

[3, 3]

其实应该这么写

 

def baz(a=None):

   a = a or []

    a.append(3)

    print a

两次调用输出以下结果:

 

[3]

[3]

 

 

 

 

这样好挫啊, 搞的虽然有默认值用法,但是我们却需要写的和js,lua一样,
我们不能像c++一样, 在函数运行时每次执行默认值么.

用decorator可以模拟下

 

复制代码

import functools

import copy

def compute_default_value_for_each_call(func):

    defaults = func.__defaults__

    if not defaults:

        return None

    defaults = tuple(copy.copy(x) for x in defaults)

 

    @functools.wraps(func)

    def wrapper(*args, **kwargs):

        if func.__defaults__ != defaults:

            func.__defaults__ = tuple(copy.copy(y) for y in
defaults)

        return func(*args, **kwargs)

 

    return wrapper

 

 

@compute_default_value_for_each_call

def foo(b, a=[]):

    if b:

        a.append(3)

    return a

 

import timeit

复制代码

这样两次调用foo(1), 结果为:

 

[3]

[3]

这个decorator有对未修改默认参数值做优化,
在我们不对默认值修改的情况下(比如打印变量a的内容), 性能有很大提升:

 

复制代码

@compute_default_value_for_each_call

def foo(b, a=[]):

    if b:

        a.append(3)

    return a

 

 

def foo2(b, a=None):

    a = a or []

    if b:

        a.append(3)

    return a

 

import timeit

 

print timeit.timeit(‘foo(1)’, setup=’from __main__ import foo’)

print timeit.timeit(‘foo(0)’, setup=’from __main__ import foo’)

print timeit.timeit(‘foo2(1)’, setup=’from __main__ import foo2′)

print timeit.timeit(‘foo2(0)’, setup=’from __main__ import foo2′)

复制代码

执行结果(调用1000000次的总时间)

 

4.32704997063

0.630109071732

0.445858955383

0.26370882988

性能上还过得去….

在调用时计算默认值
大家都知道python的默认值是在函数定义时计算出来的,
也就是说默认值只会计算一次, 之后函数调用时, 如果参数…

 

 

示例1:猜测一下,会输出什么??? 

2.1、重新认识函数

def ddd(a,b=[]):
    b.append(a)
    return b

print(ddd(1))
print(ddd(2,['a','b','c']))
print(ddd(3))

图片 1

 

     Python
中所谓的使用函数,就是把你要处理的对象放到一个名字后面的括号里。简单来说,函数就是这么使用的,往里面塞东西就可以得到处理结果。

[1] 
[‘a’,’b’,’c’,’2′] [3]   ?????你是否认为是这样? 输出一下看看

 

输出结果:

– Python 的 内建函数(Built-in Functions)

D:Python27python.exe D:/untitled1/temp5.py
[1]
['a', 'b', 'c', 2]
[1, 3]

 

 

以 Python 3.60 版本为例,一共存在 68 个这样的函数,它们被统称为
内建函数(Built-in Functions)。

看到以上结果有什么想法,为什么呢???[1,
3]而不是[3],那么修改一下代码,输出b变量的内存地址看一下。我想,可以找到我要的答案

之所以被称为内建函数,并不是因为还有“外建函数”这个概念,“内建”的意思是在
Python 3.60 版本安装完成后,你无须创建就可以直接使用这些函数,即
表示这些函数是“自带”的而已。

def ddd(a,b=[]):
    b.append(a)
    print(id(b)) #查看内存地址
    return b

print(ddd(1))
print(ddd(2,['a','b','c']))
print(ddd(3))

 

输出结果:

Python 3.60 的 68个 内建函数(Built-in Functions):

D:Python27python.exe D:/untitled1/temp5.py
170580872
[1]
171586568
['a', 'b', 'c', 2]
170580872
[1, 3]
    Built-in Functions    
abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()  
delattr() hash() memoryview() set()  

从输出中,可以看出,除了,第二个print,其它两个内存是一们的。那么考虑一下为什么第二个为被改变。结果显而易见,因为第二个print改变了,b对象,重新创建了一个对象。

 

 

 

那么如果不想出现,每次调用,默认值对象不变的问题,可以这样改一下:

2.2、创建函数

def ddd(a,b=None):
    if type(b).__name__!='list':
        b = []

    b.append(a)
    print(id(b)) #查看内存地址
    return b

print(ddd(1))
print(ddd(2,['a','b','c']))
print(ddd(3))

 

初始值设置为None,通过类型判断来,进行内处理

– Python 创建函数的格式如下:

 

 

小结:

图片 2

      
1.python定义def的时候,如果参数做为对象,那么,如果没有改变这个对象的前提下,那么即使,多次调用该函数也,不会创建新的对象。

 

         
那么就会出现多次调用函数,有可能都进行了处理。

 

  2.如果,没有特殊需求,函数参数,尽量不采用对象,如果一有需要,对象进行内处理。传默认值None

★ 重 点:

 

  ① def(即 define
,定义)的含义是创建函数,也就是定义一个函数。

  ② 闭合括号后面的 冒号( )必不可少。

  ③ 函数「缩进」后面的语句被称作
语句块(block),缩进是为了表明语句和逻辑的从属关系,是 Python
最显著的特征之一。(大部分语言会用大括号 { } 来表明这样从属关系)

  ④ return 即返回结果。在 Python 中 return 是可选的,如果没有 return
即函数的返回值为 ‘None’。 

 

☆ 注意:

  ① def 和 return 是 关键字(keyword),Python
就是靠识别这些特定的关键字来明白用户的意图,实现更为复杂的编程。

  ② 在 Python 中 return 是可选的(optional),这意味着你在创建函数时不写 return 也可以顺利地定义一个函数并调用,只不过
返回值 是 ‘None’ 罢了。

  ③ 我们把 使用函数 这种行为叫做“调用”(call)。即 调用函数 。

 

图片 3

 

# 例子,温度的单位有 摄氏度 和 华氏度
,已知 摄氏度 与 华氏度 的转化公式为:F = 9/5*C+32 。

# 现在我们创建一个能实现 摄氏度 转化为
华氏度 的函数,并调用该函数实现转化:

 

def temp_converter(c):

return str(9/5*c+32) + ‘?F’

 

c_in = input(‘请输入摄氏温度:’)

c_in = int(c_in)

f = temp_converter(c_in)

print(‘华氏温度为:’ + f)

 

 

2.3、传递参数与参数类型

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图