鱼C论坛

 找回密码
 立即注册

[技术交流] py3000愉快的开始

[复制链接]
 楼主| 发表于 2017-7-22 05:40:22 | 显示全部楼层

013元组:戴上了枷锁的列表(下)

本帖最后由 摆渡终极鉴黄师 于 2017-7-22 05:58 编辑

虽然元祖我们不能修改,但是我们可以添加啊,就像字符串那样,例如
>>> temp = (9, 5, 7)
>>> temp = temp[:2] + (2, ) + temp[2:]
>>> temp
(9, 5, 2, 7)

也可以用切片的方式间接地删除一个元素,例如
>>> del temp
>>> temp
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    temp
NameError: name 'temp' is not defined

当python发现没有任何标签指向元祖的时候,python的自动回收机制会每隔一段时间自动检查一下,Ta也会被删除的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-7-23 07:50:07 | 显示全部楼层

014字符串:各种奇葩的内置方法(上)

本帖最后由 摆渡终极鉴黄师 于 2017-7-23 08:30 编辑

>>> str1 = 'I love PC'
>>> str1[:6]
'I love'
>>> str1
'I love PC'
>>> str1[6]
' '
>>> str1[5]
'e'
>>> str1[:6] + '插入的字符串' +str1[6:]
'I love插入的字符串 PC'
>>> str1
'I love PC'
>>> str1 = str1[:6] + '插入的字符串' + str1[6:]
>>> str1
'I love插入的字符串 PC'

capitalize()        把字符串的第一个字符改为大写,例如
>>> str2= 'xiaoxie'
>>> str2.capitalize()
'Xiaoxie'

casefold()        把整个字符串的所有字符改为小写,例如
>>> str2 = "DAXIExiaoxie"
>>> str2.casefold()
'daxiexiaoxie'
>>> str2
'DAXIExiaoxie'

count(sub[,start[,end]])                返回sub在字符串里边出现的次数,start和end参数表示范围,可选。例如
>>> str2.center(40)
'              DAXIExiaoxie              '
>>> str2.count('xi')
2

endswith(sub[,start[,end]])        检查字符串是否已sub子字符串结束,如果是返回True,否则返回False。start和end参数表示范围,可选。例如
>>> str2.endswith('xi')
False

expandtabs([tabsize=8])        把字符串中的tab符号(\t)转换为空格,如不指定参数,默认的空格数是tabsize=8.例如
>>> str3 = 'I\tlove\tPC!'
>>> str3.expandtabs()
'I       love    PC!'

find(sub[,start[,end]])        检测sub是否包含在字符串中,如果有则返回索引值,否则返回-1,start和end参数表示范围,可选。例如
>>> str3.find('efc')         (找不到的话Ta会返回一个-1)
-1
>>> str3.find('PC')                (P的一个下标 索引值是7)
7

islower()                如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回True,否则返回False。例如
>>> str4 = '小甲鱼'
>>> str4.islower()
False        (跟26个字母不搭边,呵呵呵呵呵呵)

istitle()                如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回True,否则返回False。例如
>>> str5 = 'FishCool'
>>> str5.istitle()
False
>>> str5 = 'Fisher'
>>> str5.istitle()
True

join(sub)                以字符串作为分隔符,插入到sub中所有的字符串之间。例如
>>> str5.join('12345')
'1Fisher2Fisher3Fisher4Fisher5'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-7-24 10:46:00 | 显示全部楼层

014字符串:各种奇葩的内置方法(下)

本帖最后由 摆渡终极鉴黄师 于 2017-7-24 12:20 编辑

lstrip()        去掉字符串左边的所有空格,例如
>>> str6 = '         i love u.'
>>> str6.lstrip()
'i love u.'

partition(sub)                找到字符串sub,把字符串分成一个3元祖(pre_sub,sub,fol_sub),如果字符串中不包含sub则返回('原字符串',' ',' '),例如
>>> str6 = 'i love fishc'
>>> str6.partition('ov')
('i l', 'ov', 'e fishc')

replace(old, new[,count])        把字符串中的old子字符串替换成new子字符串,如果count制定,则替换不超过count次,例如
>>> str6 = 'i love fishc'
>>> str6.replace('fishc', '巨型大白鲨')
'i love 巨型大白鲨'

split(sep=None, maxsplit=-1)        不带参数默认是以空格为分隔符切片字符串,如果maxsplit参数有设置,则仅分隔maxsplit个子字符串,返回切片后的子字符串拼接的列表,例如
>>> str6.split()
['i', 'love', 'fishc']     (Ta就变成列表了,由这三个组成的列表,Ta按空格来切)

也可以以i来切,例如
>>> str6.split('i')
['', ' love f', 'shc']

strip([chars])                删除字符串前边和后边所有的空格,chars参数可以定制删除的字符,可选,例如
>>> str7 = '            mdzz'
>>> str7.strip()
'mdzz'
>>> str7 = str7.strip()
>>> str7
'mdzz'
>>> str7.strip('z')
'md'

swapcase()                翻转字符串中的大小写,例如
>>> str5 = 'Flowerk'
>>> str5
'Flowerk'
>>> str5.swapcase()
'fLOWERK'

translate(table)        根据table的规则(可以由str.maketrans('a', 'b')定制)转换字符串的字符,例如
>>> str7
'mdzz'
>>> str7.translate(str.maketrans('z', 'q'))
'mdqq'
>>> str.maketrans('z', 'q')
{122: 113}        (返回的ascll码)

这些只要知道就行了

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-7-25 08:32:08 | 显示全部楼层

015字符串:格式化(上)

本帖最后由 摆渡终极鉴黄师 于 2017-7-25 13:51 编辑

format方法,Ta需要参数的,应该这样,例如
>>> "{0} love {1}.{2}".format("I", 'FishC', 'com')
'I love FishC.com'

也可以这样,不过会出错,例如
>>> "{a} love {b}.{c}".format("I", 'FishC', 'com')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>

正确的写法,例如
    "{a} love {b}.{c}".format("I", 'FishC', 'com')
KeyError: 'a'
>>> "{a} love {b}.{c}".format(a="I", b="FishC", c="com")
'I love FishC.com'

位置参数必须在关键字参数之前,例如
>>> "{0} love {b}.{c}".format("I", b="FishC", c="com")
'I love FishC.com'

用ab引领的关键字参数,那么这个0的话就默认不会认为,Ta是一个位置参数了
>>> "{a} love {b}.{0}".format(a="I", b="FishC", "com")
SyntaxError: positional argument follows keyword argument

跟反斜杠是一个道理,只不过反斜杠是被转义掉了,0被解释掉了
>>> print('\ta')
        a
>>> print('\\')
\
>>> "{{0}}".format("不打印")   (“不打印”这个参数事实上是没有打印出来的,因为没有字段可以被输出,因为这个0已经被解释掉了)
'{0}'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-7-26 09:57:05 | 显示全部楼层

015字符串:格式化(中)

本帖最后由 摆渡终极鉴黄师 于 2017-7-26 10:24 编辑

>>> '{0:.1f}{1}'.format(27.658, 'GB')       (冒号表示格式化符号的开始,Ta后边接的就是格式化符号,这个.1的意思就是四舍五入,这个f的意思就是打出定点数,定点数跟浮点数都是差不多的,都是打印一个小数,位置参数都是差不多的,就是把GB给打印出来)
'27.7GB'

%c                格式化字符及其ASCII码,例如
>>> '%c' % 97
'a'          (python支持两种形式的输入参数,第一种是元祖,第二种是字典)

>>> '%c %c %c' % (97, 98, 99)
'a b c'

%s                格式化字符串,例如
>>> '%s' % 'I love FishC.com'
'I love FishC.com'

>>> '%d + %d = %d' % (4, 5, 4+5)
'4 + 5 = 9'

%o                格式化无符号八进制数,例如
>>> '%o' % 10
'12'

%x                格式化无符号十六进制数,例如
>>> '%x' % 10
'a'

%X                格式化无符号十六进制数(大写),例如
>>> '%X' % 10
'A'

%f                格式化定点数,可指定小数点后的精度,例如
>>> '%f' % 27.658
'27.658000'

%e                用科学计数法格式化定点数(作用同%E),例如
>>> '%e' % 27.658
'2.765800e+01'

%g                根据值的大小决定使用%f或%e(作用同%G),例如
>>> '%g' % 27.658
'27.658'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-7-27 14:35:54 | 显示全部楼层

015字符串:格式化(下)

本帖最后由 摆渡终极鉴黄师 于 2017-7-27 15:55 编辑

m.n                m是显示的最小总宽度,n是小数点后的位数,例如
>>> '%5.1f' % 27.658   
' 27.7'                (最小总宽度就是说整个字符串加起来要等于5的宽度,所以开头有个空格)

>>> '%.2e' % 27.658        (小数点左边的就是说这个字符串要占多少位,右边的就是说要精确的位数)
'2.77e+01'

>>> '%10d' % 27.658
'        27'

-        用于左对齐,例如
>>> '%-10d' % 5
'5         '                (后边的用空格填充)

+        在正数前面显示加号(+)
>>> '%+d' % 5
'+5'
>>> '%+d' % -5
'-5'

#        在八进制数前面显示零(‘o’),在十六进制数前面现实‘0x’或‘0X’,例如
>>> '%#o' % 10
'0o12'        (o表示Ta是八进制的意思)

>>> '%#X' %108
'0X6C'        (X表示Ta是十六进制的意思)

>>> '%#d' % 10
'10'                (十进制就是d嘛,Ta就什么都不显示了)

0        显示的数字前面填充‘0’取代空格,例如
>>> '%010d' % 5
'0000000005'

>>> '%-010d' % 5
'5         '     (负号的意思呢是表示左对齐,我们要显示的一个数是5的数,后面如果用0来填充就会变得非常大,所以就不显示了)


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 16:20:31 | 显示全部楼层

016序列!序列!(下)

本帖最后由 摆渡终极鉴黄师 于 2017-7-28 16:49 编辑

列表、元祖和字符串的共同点
-都可以通过索引得到每一个元素
-默认索引值总是从0开始
-可以通过分片的方法得到一个范围内的元素的集合
-有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)

list()把一个可迭代对象转换为列表

list要么是不带参数的,要么是一个迭代器

list(iterable)是一个迭代器,所谓迭代,是重复反馈过程的活动
例如
>>> a = list()
>>> a
[]
>>> b = 'I love FishC.com'
>>> b = list(b)
>>> b
['I', ' ', 'l', 'o', 'v', 'e', ' ', 'F', 'i', 's', 'h', 'C', '.', 'c', 'o', 'm']

tuple([iterable])把一个可迭代对象转换为元祖(跟list一模一样的操作)

str(obj)把obj对象转换为字符串

len()就是返回一个参数的长度,例如
>>> len(a)
0
>>>a
[]           (因为a是0,所以返回一个空列表)
>>> len(b)
16
>>> b
['I', ' ', 'l', 'o', 'v', 'e', ' ', 'F', 'i', 's', 'h', 'C', '.', 'c', 'o', 'm']                (因为b是16个字符,Ta变成了16个元素的列表)

max()返回序列或者参数集合中的最大值(反之min返回最小值),例如
>>> max(1, 2, 3, 4, 5)
5
>>> max(b)
'v'        (v在里面ascll码的值是最大的,所以就返回了一个v)
>>> numbers = [1, 18, 13, 0, -98, 34, 54, 76, 32]
>>> max(numbers)
76
>>> min(numbers)
-98

声明一个变量也行,字符串的背后也是一个ascll码,例如
>>> chars = '1234567890'       
>>> min(chars)
'0'

传进一个元祖的值也可以进行比较,例如
>>> tuple1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
>>> max(tuple1)
9

如果既有整形又有字符串,则不能进行比较,例如
>>> numbers.append('a')
>>> numbers
[1, 18, 13, 0, -98, 34, 54, 76, 32, 'a']
>>> max(numbers)
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    max(numbers)
TypeError: '>' not supported between instances of 'str' and 'int'(通过索引每一个元素把每一个元素进行对比)
max- tuple[0]
——————————————————————————————————————————————————
for each in tuple1:
        if each > max:
                max = each

return max
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-29 19:22:47 | 显示全部楼层

017函数:Python的乐高积木

本帖最后由 摆渡终极鉴黄师 于 2017-7-30 18:53 编辑

函数        对象        模块
函数,当函数发生调用的时候,Ta会网上寻找,python就会找到上边def这个关键字,找到这个函数的创建和定义过程,也就是下面这个框框里,例如
————————————————————————————————
|>>> def MyFirstFunction():                                                                          |
|        print('这是我创建的第一个函数!')                                                         |
|        print('我表示很鸡冻..')                                                                            |
|        print('在此,我要感谢KTV,感谢CCAV,感谢小甲鱼,感谢各位鱼油...')      |
————————————————————————————————
       
>>> MyFirstFunction()
这是我创建的第一个函数!
我表示很鸡冻..
在此,我要感谢KTV,感谢CCAV,感谢小甲鱼,感谢各位鱼油...

函数的一些用法,例如
>>> def MySecondFunction(name):
        print(name + '我爱你!')

       
>>> MySecondFunction('小甲鱼')
小甲鱼我爱你!
>>> MySecondFunction('老甲鱼')
老甲鱼我爱你!

>>> def add(num1, num2):
        result = num1 + num2
        print(result)

       
>>> add(1, 2)
3
(函数定义三四个就差不多了。函数的功能和参数的意义,一定要写好相应的注释,这要别人要维护的时候才不会那么费劲)

>>> def add(num1, num2):
        return (num1 + num2)

>>> print(add(5, 6))
11                (整个函数执行完后,Ta是返回num1+num2,返回11所谓print的参数)

这是函数的返回值部分的内容
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-30 19:04:31 | 显示全部楼层

018函数:灵活即强大(上)

本帖最后由 摆渡终极鉴黄师 于 2017-7-31 21:41 编辑

形参和实参
>>>def MyFirstFunction(name):
                '函数定义过程中的name是叫形参'
                #因为Ta只是一个形式,表示占据一个参数位置
                print('传递进来的' + name + '叫做实参,因为Ta是具体的参数值!')
>>>MyFirstFunction('小甲鱼')
传递进来的小甲鱼叫做实参,因为Ta是具体的参数值!

函数文档用于介绍参数,内容以及意义,返回值等等内容,例如
>>> print.__doc__
"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\nPrints the values to a stream, or to sys.stdout by default.\nOptional keyword arguments:\nfile:  a file-like object (stream); defaults to the current sys.stdout.\nsep:   string inserted between values, default a space.\nend:   string appended after the last value, default a newline.\nflush: whether to forcibly flush the stream."

这样可以转义出来,例如
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
   
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-31 23:59:34 | 显示全部楼层

018函数:灵活即强大(中)

本帖最后由 摆渡终极鉴黄师 于 2017-8-1 01:51 编辑

我们在调用函数的时候往往会搞乱顺序,例如
>>> def SaySome(name, words):
        print(name + '->' + words)

       
>>> SaySome('连接','互联网是里世界')
连接->互联网是里世界
>>> SaySome('互联网是里世界','连接')
互联网是里世界->连接

可以利用关键字参数,例如
>>> SaySome(words='互联网是里世界', name='连接')
连接->互联网是里世界

可以这样子,例如
>>> def SaySome(name='小甲鱼', words='让编程改变世界!'):
        print(name + '->' + words)

       
>>> SaySome()
小甲鱼->让编程改变世界!
>>> SaySome('天草筱')
天草筱->让编程改变世界!
>>> SaySome('天草筱','年轻人好好撸管,不要做白日梦了')
天草筱->年轻人好好撸管,不要做白日梦了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-1 17:04:48 | 显示全部楼层

018函数:灵活即强大(下)

本帖最后由 摆渡终极鉴黄师 于 2017-8-1 17:38 编辑

python就是说,把标志为收集参数的参数用一个元祖把Ta打包起来,params是收集参数,例如
>>> def test(*params):
        print('参数的长度是:', len(params));
        print('第二个参数是:', params[1]);

       
>>> test(1, '小甲鱼', 3.14, 2, 3, 3, 3)
参数的长度是: 7
第二个参数是: 小甲鱼

如果没有通过关键字参数定义,去调用的话就会出错,例如
>>> def test(*params, exp):
        print('参数的长度是:', len(params), exp);
        print('第二个参数是:', params[1]);

       
>>> test(1, '小甲鱼', 3.14, 2, 3, 3, 3)        (前面所有的内容都给了params这个收集参数了,这个exp就得不到了)
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    test(1, '小甲鱼', 3.14, 2, 3, 3, 3)
TypeError: test() missing 1 required keyword-only argument: 'exp'


有收集参数,后面还有一些其他的参数,请为这些其他的参数设置为默认参数,这样不容易出错,就算后面没有定义也不会出错,例如
>>> def test(*params, exp = 8):
        print('参数的长度是:', len(params));
        print('第二个参数是:', params[1]);

       
>>> test(1, '小甲鱼', 3.14, 2, 3, 3, 3)
参数的长度是: 7
第二个参数是: 小甲鱼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-2 20:55:27 | 显示全部楼层

019函数:我的地盘听我的(上)

本帖最后由 摆渡终极鉴黄师 于 2017-8-3 04:03 编辑

python严格来说只有函数,没有过程,例如
>>> def hello():
        print('Hello World')

       
>>> temp = hello()
Hello World
>>> temp
>>> print(temp)
None
>>> type(temp)
<class 'NoneType'>
python所有函数都是会返回某些东西的

一个函数是整形的函数,这个函数会返回一个整形的返回值,而python不这么干,pythonTa是动态的确定类型,只有Ta赋值的时候编辑器会自动确定这个需要的类型,python只有变量没有名字,python也可以返回多个值,例如
>>> def back():
        return [1, '小甲鱼', 3.14]

>>> back()
[1, '小甲鱼', 3.14]
>>> def back():
        return 1, '小甲鱼', 3.14

>>> back()
(1, '小甲鱼', 3.14)
事实上Ta是利用一个元祖把这多个值打包成一个数据返回
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-3 16:49:05 | 显示全部楼层

019函数:我的地盘听我的(下)

本帖最后由 摆渡终极鉴黄师 于 2017-8-3 17:48 编辑

函数变量的作用域问题,局部变量和全局变量,例如
def discounts(price, fate):
        final_price = price * rate
        return final_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price, rate)
print('打开后的价格是:', new_price)

================ RESTART: C:/Users/Administrator/Desktop/1.py ================
请输入原价:200
请输入折扣率:0.5
打开后的价格是: 100.0


其中price, rate, final_price为局部变量,如果这么改,例如
def discounts(price, fate):
        final_price = price * rate
        return final_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price, rate)
print('打开后的价格是:', new_price)
print('这里试图打印局部变量final_price的值:', final_price)


================ RESTART: C:/Users/Administrator/Desktop/1.py ================
请输入原价:200
请输入折扣率:0.5
打开后的价格是: 100.0
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/1.py", line 9, in <module>
    print('这里试图打印局部变量final_price的值:', final_price)
NameError: name 'final_price' is not defined) #因为final_price只是一个局部变量,Ta在局部里边生效的,这里只在def里面生效,当def执行完之后局部变量会自动被删除




全局变量则就可以,例如
def discounts(price, fate):
        final_price = price * rate
        print('这里试图打印全局变量old_price的值', old_price)
        return final_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price, rate)
print('打开后的价格是:', new_price)


================ RESTART: C:/Users/Administrator/Desktop/1.py ================
请输入原价:200
请输入折扣率:0.5
这里试图打印全局变量old_price的值 200.0
打开后的价格是: 100.0

如果这样改,例如
def discounts(price, fate):
        final_price = price * rate
        # print('这里试图打印全局变量old_price的值', old_price)
        old_price = 50
        print('修改后old_price的值是1:', old_price)
        return final_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price, rate)
print('修改后old_price的值是2:', old_price)
print('打开后的价格是:', new_price)


================ RESTART: C:/Users/Administrator/Desktop/1.py ================
请输入原价:200
请输入折扣率:0.5
修改后old_price的值是1: 50
修改后old_price的值是2: 200.0 #这样是因为如果试图在函数内修改全局变量的话,python会自动创建一个新的局部变量代替,存放在其他空间,Ta名字跟全局变量的名字是一模一样的,而下面的代码存放在栈空间,Ta们是互不影响的,同时存在的,所以上边打印old_price的是python新创建的局部变量的值而下(外)边打印的old_price是全局变量的值,所以不一样
打开后的价格是: 100.0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-4 23:06:34 | 显示全部楼层

020函数:内嵌函数和闭包(上)

本帖最后由 摆渡终极鉴黄师 于 2017-8-5 00:53 编辑

global关键字
上一课说,一旦函数内部试图修改全局变量的时候,python就会自动创建一个名字一模一样的局部变量,这样的话,修改的结果只会修改到python创建的局部变量而不会影响到全局变量,但是python有个屏蔽(Shadowing)机制,例如
>>> count = 5
>>> def MyFun():
        count = 10
        print(10)

       
>>> MyFun()
10                        #下面那个局部变量count把上面那个全局变量count屏蔽了,这就是python的shadowing机制       
>>> print(count)
5                        #因为count = 10针对的是局部变量所以全局变量不会受到影响       

但是我们可以用global关键字来达到目的
>>> def MyFun():
        global count
        count = 10
        print(10)

       
>>> MyFun()
10                       
>>> print(count)
10                        #global修饰之后的关键字就变成了全局变量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-5 23:54:05 | 显示全部楼层

020函数:内嵌函数和闭包(中)

本帖最后由 摆渡终极鉴黄师 于 2017-8-7 00:03 编辑

内嵌函数
允许在函数内部创建另一个函数叫做内嵌函数,或者称之为内部函数,例如
>>> def fun1():
        print('fun1()正在被调用...')
        def fun2():
                print('fun2()正在被调用...')
        fun2()

       
>>> fun1()
fun1()正在被调用...
fun2()正在被调用...
>>> fun2()                #由于嵌套了fun2(),所以fun2()Ta看不到
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    fun2()
NameError: name 'fun2' is not defined

闭包是函数式编程重要的一个语法结构,函数式编程Ta是一种编程范式,面向对象编程,面向过程编程,这些都是一种编程范式,这些编程范式呢就是对代码进行提炼和抽象和概括,使得代码的重用性可用性更高。
从表现形式定义为——如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就会被认为是闭包,例如
>>> def FunX(x):                #外部作用域就是 def FunX(x):        到return FunY整个函数的空间
        def FunY(y):                #这一行是内部函数FunY
                return x * y        #这一行也是内部函数#变量x对Ta进行引用了,内部函数FunY就会被认为是闭包
        return FunY

>>> i = FunX(8)
>>> i
<function FunX.<locals>.FunY at 0x0000000002FC4E18>
>>> type(i)
<class 'function'>#由此可知,i跟FunX一样是一个function,因为i是函数的函数

如果要得到x * y的值我们还需要对y进行调用一次,例如
>>> i(5)
40
>>> FunX(8)(5)
40

我们也不能在外部函数的外边,对内部函数进行调用(只能进行访问),例如
>>> FunY(5)
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    FunY(5)
NameError: name 'FunY' is not defined

在闭包中,外部函数的局部变量对内部函数的局部变量,事实上就相当于上一课的全局变量和局部变量的关系,再举个栗子,例如
>>> def Fun1():
        x = 5                #Fun2的整个外部空间也在Fun1的内部空间里,这行的x = 5在Fun2函数的外部作用域里边
        def Fun2():
                x *= x        #执行这行代码的时候,外部函数x会被屏蔽起来,所以会导致无法操作
                return x
        return Fun2()

>>> Fun1()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    Fun1()
  File "<pyshell#34>", line 6, in Fun1
    return Fun2()
  File "<pyshell#34>", line 4, in Fun2
    x *= x
UnboundLocalError: local variable 'x' referenced before assignment

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-7 00:02:34 | 显示全部楼层

020函数:内嵌函数和闭包(下)

本帖最后由 摆渡终极鉴黄师 于 2017-8-7 00:40 编辑

列表的话不是存放在栈里边,所以我们可以改成列表的形式就不会导致问题的出现的,例如
>>> def Fun1():
        x = [5]
        def Fun2():
                x[0] *= x[0]
                return x[0]
        return Fun2()

>>> Fun1()
25

我们可以强行声明Ta不是一个局部变量,也可以不会报错,例如
>>> def Fun1():
        x = [5]
        def Fun2():
                nonlocal x                #这条语句
                x[0] *= x[0]
                return x[0]
        return Fun2()

>>> Fun1()
25
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-7 23:57:37 | 显示全部楼层

021函数:lambda表达式(上)

本帖最后由 摆渡终极鉴黄师 于 2017-8-9 01:07 编辑

命名函数lambda的使用,例如
>>> def ds(x):
        return 2 * x + 1

>>> ds(5)
11
>>> lambda x : 2 * x + 1                #:前面是原函数的参数,:后面是原函数的返回值
<function <lambda> at 0x0000000002FC4A60>

lambda的语句事实上是构建了一个函数对象,Ta是返回一个function object,如果需要对其进行使用,我们只需要简单的进行赋值就可以了,例如
>>> g = lambda x : 2 * x + 1                #少了一个def的过程,也不用为这个函数命名而烦恼了,因为这个函数是匿名的,随便给个名字赋值一下就可以使用了,用完之后内存的垃圾清洁器,当Ta不被使用的时候会自动把Ta删除掉
>>> g(5)
11

冒号前面的参数可以是多个的,例如
>>> def add(x, y):
        return x + y

>>> add(3, 4)
7
>>> lambda x, y : x + y
<function <lambda> at 0x0000000002FC4B70>
>>> g = lambda x, y : x + y
>>> g(3, 4)
7

lambda表达式的作用
Python写一些执行代码时,使用lambda就可以省下定义函数过程,比如说我们只是需要写个简单的代码来管理服务器时间,我们就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简。
对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的问题了。
简化代码的可读性,由于普通的屌丝函数阅读经常要跳到开头def定义部分,使用lambda函数可以省去这样的步骤。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-8 23:44:22 | 显示全部楼层

021函数:lambda表达式(下)

本帖最后由 摆渡终极鉴黄师 于 2017-8-9 01:32 编辑

两个牛逼的BIF
filter()叫做过滤器,就是用来筛选,例如

>>> filter(None, [1, 0, False, True])
<filter object at 0x0000000002FBBF60>                #Ta返回的是一个可迭代的对象


>>> list(filter(None, [1, 0, False, True]))                #Ta把非True筛选掉了
[1, True]

>>> def odd(x):
        return x % 2

>>> temp = range(10)
>>> show = filter(odd, temp)                                #只要给Ta函数的名字就可以了
>>> list(show)
[1, 3, 5, 7, 9]

可以把Ta们简化为一行,例如
>>> list(filter(lambda x : x % 2, range(10)))
[1, 3, 5, 7, 9]

map()将序列的每一个元素,作为函数的参数,进行运算加工,直到,可迭代序列的,每个元素,都加工完毕,返回,所有加工后的,元素,构成的新序列,例如
>>> list(map(lambda x : x * 2, range (10)))                #后面的range(10)的0123456789放到前面的x里作为参数,然后依次乘以2通过列表的方式显示出来
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-9 23:47:51 | 显示全部楼层

022函数:递归是神马(上)

本帖最后由 摆渡终极鉴黄师 于 2017-8-10 03:45 编辑

递归就是函数调用自身的这么一个行为,例如
>>> def recursion():
        return recursion()

>>> recursion()
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    recursion()
  File "<pyshell#2>", line 2, in recursion
    return recursion()
  File "<pyshell#2>", line 2, in recursion
    return recursion()
  File "<pyshell#2>", line 2, in recursion
    return recursion()
  [Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceeded
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-11 10:00:49 | 显示全部楼层

022函数:递归是神马(下)

本帖最后由 摆渡终极鉴黄师 于 2017-8-12 11:13 编辑

可以用递归求阶乘,普通版求阶乘可以这样,例如
def factorial(n):
        result = n
        for i in range(1, n):
            result *= i


        return result

number = int(input('请输入一个正整数:'))
result = factorial(number)
print("%d 的阶乘是:%d" % (number, result))

递归版
def factorial(n):
    if n == 1
        return 1
    else:
        return n * factorial(n-1)

number = int(input('请输入一个正整数:'))
result = factorial(number)
print("%d 的阶乘是: %d" % (number,result))
满足递归有两个条件:有调用函数自身的行为,有一个正确的返回条件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 09:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表