
正文
python函数绑定值 python绑核
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
python怎么看函数备选值
1、默认参数:放在必选参数之后,计算x平方的函数: 这样的话每次计算不同幂函数都要重写函数,非常麻烦,可使用以下代码计算: 默认参数最大好处就是降低调用函数的难度。
2、可变参数:就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个,在参数前面加上*就是可变参数。在函数内部,参数numbers接收得到的是一个tuple,调用该函数时,可以传入任意个参数,包括0个参数: 也可以类似可变参数,先组装一个dict,然后,把该dict转换为关键字参数传进去: python怎么看函数的实现 系统内置的类是内置实现的,没有相关代码。 如果要看,只能找python的源代码来看_str的实现,但那里头也没有多少,大部分都是调用外部库实现的,没多少python代码。 一些python包中的功能,可以直接看相应的py文件的代码。 或者按下述方式: 启动MoleDocs: 同时会弹出的浏览器窗口: 在其中选择相应的包,比如re包: 点击红框处的连接即可以浏览器中查看相应py文件的代码,或者在ide中打开相应的文件去查看。 如果某个包的方法调用产生了错误,可以在ide中点击相应的连接以打开相应的py文件并定位到出错语句,这对所有的py文件都是有效的,但不是所有的ide都会有此功能。 如何查看python库函数的代码 python所有版本的源代码可以在这里下载到: python没有像matlab那样的函数可以直接查看某个函数的源代码,只有去下载整个源代码查看了,不过找起来应该也不难,另外你也可以写一个小程序来查看对应函数的源代码
相关问答
Q1: 求帮助,Python闭包和返回函数问题
(1)unpack tuple和list, 可以让函数返回多个值
def count():
return (1, 2, 3) # 或者 return [1, 2, 3]
# 把列表解包,把1 2 3 分别赋值给 a b c
a, b, c = count()
print a, b, c
# 输出 1, 2, 3
(2)假设你知道Python的dict类型。Python中,在函数中定义一个变量的时候,会在一个隐藏的叫locals的dict里面插入key-value,其中key是变量名,value是变量值。而引用一个变量的时候,则首先会在这个叫locals的dict里面,根据变量名作为key,去查对应的值。
var = 1 # 你可以认为这里进行了 locals['var'] = 1 的操作
print var # 在对var变量进行求值的时候,就在locals['var']里面找var变量对应的值
(3)for循环中,每次循环只是给 `i` 重新绑定值
for i in (1, 2, 3):
print i
print i
# 一次输入 1 2 3 3
每次`for i in (1, 2, 3)`相当于在`print i`之前,进行了
`locals['i'] = 1`
`locals['i'] = 2`
`locals['i'] = 3`
的操作
所以最后的`print i`再去locals字典里面找`i`的时候,就变成 3 了。
(4)闭包是 一个函数加上这个函数引用的外部变量
var = 1
def f():
print var
# 这里的闭包是函数 f 和 f 引用的外部变量 var
def count():
var2 = 2
def f():
print var2
# 这里的闭包是函数 f 和 f 引用的外部变量 var2
return f
拿第一个函数 f 来说。在 f 运行的时候,解释器拿着'var'这个字符串去locals字典里面找,发现找不到,于是在closure字典里面找,最后closure字典里面找,你可以认为就是找closure['var'],然后发现找到对应的值。count里面的 f 函数同理。
(为了容易理解,我这里说谎了。实际上 f 压根没有closure,count里面的 f 才有。其实closure压根不是像locals那样的字典)
(5)函数定义时,函数只是记录变量的名字。
要区分什么是名字,什么是值。
`i = 1`这里 i 只是名字,只是一个字符串 'i' 。这句话运行完,locals['i'] = 1,就说 i 对应的值是1
def count():
fs = []
for i in range(1, 4):
# 定义一个函数,等价于运行了 locals['f'] = 真正生成的函数
# 每次循环,这里都会重新生成一个函数,然后把重新生成的函数赋值给 locals['f']
def f():
return i * i # 引用了'i'这个名字,但并不是引用了'i'对应的值
# 等价于 locals['fs'].append(locals['f'])
# f 不是函数,它只是一个名字'f'。f 引用的东西,也就是locals['f']才是真正的函数
fs.append(f)
# 于是这个for循环生成了三个函数,这三个函数是没有名字的,这个函数运行完后,它们跟'f'这个名字就毛关系都没有了(是的我说慌了,但可以先不管)
# 把整个列表返回,这个列表包含了三个函数
return fs
# count()返回三个函数的列表,unpack 列表的语法把列表中的三个函数抽出来,重新给他们命名为 f1, f2, f3
# 也就是说,
# locals['f1'] = 列表中的第1个函数
# locals['f2'] = 列表中的第2个函数
# locals['f3'] = 列表中的第3个函数
# 这三个函数跟'f'这个名字现在毛关系都没有。(其实是有的,但为了说明需要简化,现在你可以完全不管括号里面说的话)
f1, f2, f3 = count()
print f1(), f2(), f3()
# 好了我们运行它们,输入都是 9
# def f():
# return i * i
这是因为 f1 现在对应的函数,里面引用了 'i' 这个字符串,我们根据 'i '这个字符串去找它对应的值,先找到 f 当前的locals字典,发现没有,因为函数定义的时候没有定义 i 变量。然后再去closure['i']里面找,因为Python是通过closure字典实现闭包的(就当它是对的好不好),所以我们可以在closure['i']找到值,这个值就是我们上一次运行的时候count函数里面残留的locals['i'],而由于for循环三遍之后,locals['i'] == 3,所以找到 i 的值就是3。所以最后输出都是9
Q2: Python中的10条冷门知识
下面时Python中一些不常见的冷门知识,感兴趣的小伙伴不妨来学习一下。
1、省略号也是对象
… 这是省略号,在Python中,一切皆对象。它也不例外。在 Python 中,它叫做 Ellipsis 。在 Python 3 中你可以直接写…来得到这玩意。
...
Ellipsis
type(...)
class 'ellipsis'
而在 Python2 中没有…这个语法,只能直接写Ellipsis来获取。
Ellipsis
Ellipsis
type(Ellipsis)
type 'ellipsis'
它转为布尔值时为真
bool(...)
True
最后,这东西是一个单例。
id(...)
4362672336
id(...)
4362672336
这东西有啥用呢?据说它是Numpy的语法糖,不玩 Numpy 的人,可以说是没啥用的。
在网上只看到这个 用 … 代替 pass ,稍微有点用,但又不是必须使用的。
try:
1/0
except ZeroDivisionError:
...
2、增量赋值的性能更好
诸如 += 和 *= 这些运算符,叫做 增量赋值运算符。这里使用用 += 举例,以下两种写法,在效果上是等价的。
# 第一种
a = 1 ; a += 1
# 第二种
a = 1; a = a + 1
+= 其背后使用的魔法方法是 iadd,如果没有实现这个方法则会退而求其次,使用 add 。
这两种写法有什么区别呢?
用列表举例 a += b,使用 add 的话就像是使用了a.extend(b),如果使用 add 的话,则是 a = a+b,前者是直接在原列表上进行扩展,而后者是先从原列表中取出值,在一个新的列表中进行扩展,然后再将新的列表对象返回给变量,显然后者的消耗要大些。
所以在能使用增量赋值的时候尽量使用它。
3、and 和or 的取值顺序
and 和 or 是我们再熟悉不过的两个逻辑运算符。而我们通常只用它来做判断,很少用它来取值。
如果一个or表达式中所有值都为真,Python会选择第一个值,而and表达式则会选择第二个。
(2 or 3) * (5 and 7)
14 # 2*7
4、修改解释器提示符
import sys
sys.ps1
' '
sys.ps2
'... '
sys.ps2 = '---------------- '
sys.ps1 = 'Python编程时光'
Python编程时光for i in range(2):
---------------- print (i)
----------------
5、默认参数最好不为可变对象
函数的参数分三种
可变参数
默认参数
关键字参数
今天要说的是,传递默认参数时,新手很容易踩雷的一个坑。
先来看一个示例:
def func(item, item_list=[]):
item_list.append(item)
print(item_list)
func('iphone')
func('xiaomi', item_list=['oppo','vivo'])
func('huawei')
在这里,你可以暂停一下,思考一下会输出什么?
思考过后,你的答案是否和下面的一致呢
['iphone']
['oppo', 'vivo', 'xiaomi']
['iphone', 'huawei']
如果是,那你可以跳过这部分内容,如果不是,请接着往下看,这里来分析一下。
Python 中的 def 语句在每次执行的时候都初始化一个函数对象,这个函数对象就是我们要调用的函数,可以把它当成一个一般的对象,只不过这个对象拥有一个可执行的方法和部分属性。
对于参数中提供了初始值的参数,由于 Python 中的函数参数传递的是对象,也可以认为是传地址,在第一次初始化 def 的时候,会先生成这个可变对象的内存地址,然后将这个默认参数 item_list 会与这个内存地址绑定。在后面的函数调用中,如果调用方指定了新的默认值,就会将原来的默认值覆盖。如果调用方没有指定新的默认值,那就会使用原来的默认值。
在这里插入图片描述
6、访问类中的私有方法
大家都知道,类中可供直接调用的方法,只有公有方法(protected类型的方法也可以,但是不建议)。也就是说,类的私有方法是无法直接调用的。
这里先看一下例子
class Kls():
def public(self):
print('Hello public world!')
def __private(self):
print('Hello private world!')
def call_private(self):
self.__private()
ins = Kls()
# 调用公有方法,没问题
ins.public()
# 直接调用私有方法,不行
ins.__private()
# 但你可以通过内部公有方法,进行代理
ins.call_private()
既然都是方法,那我们真的没有方法可以直接调用吗?
当然有啦,只是建议你千万不要这样弄,这里只是普及,让你了解一下。
# 调用私有方法,以下两种等价
ins._Kls__private()
ins.call_private()
7、时有时无的切片异常
这是个简单例子
my_list = [1, 2, 3, 4, 5]
print(my_list[5])
Traceback (most recent call last):
File "F:/Python Script/test.py", line 2, in module
print(my_list[5])
IndexError: list index out of range
来看看,如下这种写法就不会报索引异常,执行my_list[5:],会返回一个新list:[]。
my_list = [1, 2, 3]
print(my_list[5:])
8、for 死循环
for 循环可以说是 基础得不能再基础的知识点了。但是如果让你用 for 写一个死循环,你会写吗?(问题来自群友 陈**)
这是个开放性的问题,在往下看之前,建议你先尝试自己思考,你会如何解答。
好了,如果你还没有思路,那就来看一下 一个海外 MIT 群友的回答:
for i in iter(int, 1):pass
是不是懵逼了。iter 还有这种用法?这为啥是个死循环?
这真的是个冷知识,关于这个知识点,你如果看中文网站,可能找不到相关资料。
还好你可以通过 IDE 看py源码里的注释内容,介绍了很详细的使用方法。
原来iter有两种使用方法,通常我们的认知是第一种,将一个列表转化为一个迭代器。
而第二种方法,他接收一个 callable对象,和一个sentinel 参数。第一个对象会一直运行,直到它返回 sentinel 值才结束。
在这里插入图片描述
那int 呢,这又是一个知识点,int 是一个内建方法。通过看注释,可以看出它是有默认值0的。你可以在终端上输入 int() 看看是不是返回0。
在这里插入图片描述
由于int() 永远返回0,永远返回不了1,所以这个 for 循环会没有终点。一直运行下去。
9、奇怪的字符串
字符串类型作为 Python 中最常用的数据类型之一,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化。
例如:Python 解释器中使用了 intern(字符串驻留)的技术来提高字符串效率。
什么是 intern 机制?就是同样的字符串对象仅仅会保存一份,放在一个字符串储蓄池中,是共用的,当然,肯定不能改变,这也决定了字符串必须是不可变对象。
示例一
# Python2.7
a = "Hello_Python"
id(a)
32045616
id("Hello" + "_" + "Python")
32045616
# Python3.7
a = "Hello_Python"
id(a)
38764272
id("Hello" + "_" + "Python")
32045616
示例二
a = "MING"
b = "MING"
a is b
True
# Python2.7
a, b = "MING!", "MING!"
a is b
True
# Python3.7
a, b = "MING!", "MING!"
a is b
False
示例三
# Python2.7
'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False
# Python3.7
'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
True
示例四
s1="hello"
s2="hello"
s1 is s2
True
# 如果有空格,默认不启用intern机制
s1="hell o"
s2="hell o"
s1 is s2
False
# 如果一个字符串长度超过20个字符,不启动intern机制
s1 = "a" * 20
s2 = "a" * 20
s1 is s2
True
s1 = "a" * 21
s2 = "a" * 21
s1 is s2
False
s1 = "ab" * 10
s2 = "ab" * 10
s1 is s2
True
s1 = "ab" * 11
s2 = "ab" * 11
s1 is s2
False
10、两次return
我们都知道,try…finally… 语句的用法,不管 try 里面是正常执行还是报异常,最终都能保证finally能够执行。
同时,我们又知道,一个函数里只要遇到 return 函数就会立马结束。
基于以上这两点,我们来看看这个例子,到底运行过程是怎么样的?
def func():
... try:
... return 'try'
... finally:
... return 'finally'
...
func()
'finally'
惊奇的发现,在try里的return居然不起作用。
原因是,在try…finally…语句中,try中的return会被直接忽视,因为要保证finally能够执行。
Q3: python中视图函数传值的数据类型可以传对象吗
python的一切数据类型都是对象。但是python的对象分为不可变对象和可变对象。python的变量是引用,对python变量的赋值是引用去绑定该对象。
可变对象的数据发生改变,例如列表和字典,引用不会更改绑定对象,毕竟本身就是用于增删改查的,频繁地产生新对象必然导致开销巨大,只需要该对象内部变化就行;但对于绑定了不可变对象的引用,对象一旦改变就会使引用绑定新的对象。
这一点也会反应到函数的参数上。python的传值方式是“传对象”引用。python的函数,形参实际上是引用,实参便是对象绑定到该引用上。本质是形参会被作为函数的局部变量,在开辟的函数的栈内存中被声明。
简要来讲:
如果参数是数,则类似值传递,
如果参数是列表和字典,则类似引用传递。
每个对象都会有个id, 可以用id()验证以上说法:
这个函数的参数是列表,是可变对象。
Q4: Python中定义函数默认参数值的使用注意事项?
4.7.1. 默认参数值
最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义是允许的参数更少的参数调用的函数,例如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no', 'nop', 'nope'):
return False
retries = retries - 1
if retries 0:
raise OSError('uncooperative user')
print(complaint)
这个函数可以通过几种不同的方式调用:
只给出必要的参数:
ask_ok('Do you really want to quit?')
给出一个可选的参数:
ask_ok('OK to overwrite the file?', 2)
或者给出所有的参数:
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
这个例子还介绍了 in 关键字。它测定序列中是否包含某个确定的值。
默认值在函数 定义 作用域被解析,如下所示:
i = 5
def f(arg=i):
print(arg)
i = 6
f()
将会输出 5。
重要警告: 默认值只被赋值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
这将输出:
[1]
[1, 2]
[1, 2, 3]
如果你不想让默认值在后续调用中累积,你可以像下面一样定义函数:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
Q5: Python-嵌套函数中的局部变量?
嵌套函数在执行时(而不是在定义时)从父范围中查找变量。
编译函数主体,然后验证“自由”变量(未在函数本身中通过赋值定义),然后将其作为闭包单元绑定到函数,并且代码使用索引引用每个单元格。pet_function因此具有一个自由变量(cage),然后将其通过一个闭合单元引用,索引为0的闭合本身指向局部变量cage在get_petters功能。
当你实际调用该函数时,该闭包将用于在你调用该函数时查看cage周围作用域中的值。问题就在这里。在你调用函数时,该函数已经完成了对其结果的计算。将在在执行过程中的一些点局部变量分配各的,和字符串,但在功能的结束,包含了最后一个值。因此,当你调用每个动态返回的函数时,就会得到打印的值。get_petterscage'cow''dog''cat'cage'cat''cat'
解决方法是不依赖闭包。你可以改用部分函数,创建新的函数作用域或将变量绑定为关键字parameter的默认值。
部分函数示例,使用functools.partial():
from functools import partialdef pet_function(cage=None):
print "Mary pets the " + cage.animal + "."yield (animal, partial(gotimes, partial(pet_function, cage=cage)))
创建一个新的范围示例:
def scoped_cage(cage=None):
def pet_function():
print "Mary pets the " + cage.animal + "."
return pet_functionyield (animal, partial(gotimes, scoped_cage(cage)))
将变量绑定为关键字参数的默认值:
def pet_function(cage=cage):
print "Mary pets the " + cage.animal + "."yield (animal, partial(gotimes, pet_function))
无需scoped_cage在循环中定义函数,编译仅进行一次,而不是在循环的每次迭代中进行。
python函数绑定值的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于python绑核、python函数绑定值的信息别忘了在本站进行查找喔。






