作者:PyQuant
博客:https://blog.csdn.net/qq_33499889
慕課:https://mooc1-2.chaoxing.com/course/207443619.html
點贊、關注再看,養成良好習慣
Life is short, U need Python
初學Python,快來點我吧
文章目錄
1. 函數對象
Python中任何東東皆爲對象,當然函數也是對象。
- 函數可以被賦值
- 函數可以當成參數傳遞
- 函數可以當成返回值
- 函數可以當成容器類型的元素
def foo():
x = 100
print(x)
print(foo)
f = foo # 函數可以被賦值
print(f)
f()
<function foo at 0x00000268BBEC2B70>
<function foo at 0x00000268BBEC2B70>
100
def foo():
x = 100
print(x)
def bar(func): # 把函數當參數
print(func)
func()
bar(foo)
<function foo at 0x00000268BBEC2D90>
100
def foo():
x = 100
print(x)
def bar(func):
print(func)
return func # 把函數當返回值
f = bar(foo)
print(f)
f()
<function foo at 0x00000268BBEC2730>
<function foo at 0x00000268BBEC2730>
100
2. 閉包
- 閉包是由函數及其相關的引用環境組合而成的實體。
- 閉包必須是內部定義函數,該函數包含對外部作用域而不是全局作用域名字的引用;沒值的話會返回None。
def ext_f(a):
x = 100
def int_f():
num = x + a
print(num)
return
return int_f
f = ext_f(10)
print(f)
print(f())
print(f.__closure__[0].cell_contents)
print(f.__closure__[1].cell_contents)
<function ext_f.<locals>.int_f at 0x00000268BBEC2EA0>
110
None
10
100
def ext_f(a):
x = 100
def int_f(b):
num = x + a + b
print(num)
return 'python'
return int_f
f = ext_f(10)
print(f)
print(f(20))
print(f.__closure__[0].cell_contents)
print(f.__closure__[1].cell_contents)
<function ext_f.<locals>.int_f at 0x00000268BBEC2BF8>
130
python
10
100
- 註釋:咋看像是爲後面的類做鋪墊呢???
3. 第一器-----裝飾器
- 裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。
- 簡單地講,裝飾器的作用就是爲已經存在的對象添加額外的功能。
【1】嵌套函數
def book(name):
return 'My name is {}'.format(name)
def foo(func):
def wrapper(name):
return '*** {} ***'.format(func(name))
return wrapper
b = foo(book)
r = b('Python')
print(r)
*** My name is Python ***
【2】簡單裝飾器
def decorator(func):
def wrapper(name):
return '*** {} ***'.format(func(name))
return wrapper
@decorator # 簡單裝飾器,其中符號 @ 是裝飾器語法標記
def book(name):
return 'My name is {}'.format(name)
r1 = book('Java')
print(r1)
*** My name is Java ***
【3】參數裝飾器
def foo(author):
def decorator(func):
def wrapper(name):
if author == 'quant':
return '*** {} ***'.format(func(name))
return wrapper
return decorator
@foo(author='quant') # 帶參數的裝飾器1
def book(name):
return 'My name is {}'.format(name)
r2 = book('Matlab')
r2
'*** My name is Matlab ***'
def foo(author):
def decorator(func):
def wrapper(name):
if author == 'quant':
return '*** {} ***'.format(func(name))
else:
return '$$$ {} $$$'.format(func(name))
return wrapper
return decorator
@foo(author='zhang') # 帶參數的裝飾器2
def book(name):
return 'My name is {}'.format(name)
r3 = book('Matlab')
r3
'$$$ My name is Matlab $$$'
【4】類裝飾器
class Foo:
def __init__(self, func):
self._func = func
def __call__(self):
print ('I like Python')
self._func()
print ('I like Java')
@Foo
def bar():
print ('bar')
bar()
I like Python
bar
I like Java
等價於
class Foo:
def __init__(self, func):
self._func = func
def __call__(self):
print ('I like Python')
self._func()
print ('I like Java')
def bar():
print ('bar')
b = Foo(bar)
b()
I like Python
bar
I like Java
4. 第二器-----生成器
-
在 Python 中,使用了 yield 的函數被稱爲 生成器(generator)。
-
跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個 迭代器(iterator)。
-
調用一個生成器函數,返回的是一個迭代器對像。
【1】函數生成器
def func(n):
for i in range(n):
yield i**2
g = func(4) # g 是一個迭代器,由生成器返回生成
print(g)
print(list(g))
<generator object func at 0x00000268BBEEE200>
[0, 1, 4, 9]
【2】表達式生成器—元組解析式(有點像列表解析式)
t = (x**2 for x in range(4))
print(t)
print(tuple(t))
<generator object <genexpr> at 0x00000268BBEEE4C0>
(0, 1, 4, 9)
【3】元組生成器 VS 列表解析式
import time
import sys
# 解析式
%time lst = [x + 1 for x in range(100000000)] # 查看運行時間
print(sys.getsizeof(lst)) # 查看python對象的內存佔用
# 生成器
%time g = (x + 1 for x in range(100000000)) # 查看運行時間
print(sys.getsizeof(g)) # 查看python對象的內存佔用
Wall time: 12.5 s
859724472
Wall time: 0 ns
88
- 結論:生成器遠遠優於解析式!
5. 第三器-----迭代器
【1】可迭代對象
Python中任何可以循環的東東都是可迭代對象(iterable)。容器類型數據(str、list、tuple、dict、set等)都可以被for循環,因此都是可迭代對象。
- isinstance(x, Iterable)
from collections import Iterable
print(isinstance(1234, Iterable))
print(isinstance('1234', Iterable))
print(isinstance([1,2,3,4], Iterable))
print(isinstance((1,2,3,4), Iterable))
print(isinstance({'a':1,'b':2}, Iterable))
print(isinstance({1,2,3,4}, Iterable))
False
True
True
True
True
True
- **dir(x)**查看是否包含
__iter__
print(dir([1,2,3]))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
【2】迭代器
-
迭代器是Python最強大的功能之一,是訪問集合元素的一種方式。
-
迭代器是一個可以記住遍歷的位置的對象。
-
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。
-
迭代器有兩個基本的方法:iter() 和 next()。
-
字符串、列表、元組、字典和集合都可用於創建迭代器,但它們不是迭代器。
-
iter
迭代器
list=[1,2,3]
myiter = iter(list) # 創建迭代器對象
print (next(myiter))
print (next(myiter))
print (next(myiter))
1
2
3
list=[1,2,3]
myiter = iter(list)
for i in myiter:
print(i)
1
2
3
- 類迭代器
class MyNumbers:
def __init__(self):
self.a = 1
def __iter__(self):
return self
def __next__(self):
b = self.a
self.a += 1
return b
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
1
2
3
print(next(myiter))
4
- 內置迭代器
import itertools
print(dir(itertools))
['__doc__', '__loader__', '__name__', '__package__', '__spec__', '_grouper', '_tee', '_tee_dataobject', 'accumulate', 'chain', 'combinations', 'combinations_with_replacement', 'compress', 'count', 'cycle', 'dropwhile', 'filterfalse', 'groupby', 'islice', 'permutations', 'product', 'repeat', 'starmap', 'takewhile', 'tee', 'zip_longest']
mycounter = itertools.count() # 計數器
print(next(mycounter))
print(next(mycounter))
print(next(mycounter))
0
1
2
data = [100,200,300]
mycounter = zip(itertools.count(), data)
print(mycounter)
for i in mycounter:
print(i)
<zip object at 0x00000268BBF04148>
(0, 100)
(1, 200)
(2, 300)
data = [100,200,300]
mycounter = zip(itertools.count(start=10), data)
for i in mycounter:
print(i)
(10, 100)
(11, 200)
(12, 300)
data = [100,200,300]
mycounter = zip(itertools.count(start=10,step=10), data)
for i in mycounter:
print(i)
(10, 100)
(20, 200)
(30, 300)
6. StopIteration
StopIteration 異常用於標識迭代的完成,防止出現無限循環的情況,在 next() 方法中我們可以設置在完成指定循環次數後觸發 StopIteration 異常來結束迭代
list = [1,2,3]
myiter = iter(list) # 創建迭代器對象
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
1
2
3
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-26-6e3259c059c9> in <module>()
5 print(next(myiter))
6 print(next(myiter))
----> 7 print(next(myiter))
StopIteration:
list = [1,2,3]
myiter = iter(list) # 創建迭代器對象
for i in myiter:
print(i)
1
2
3
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 3:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
1
2
3
- 寫作不易,切勿白剽
- 博友們的點贊和關注就是對博主堅持寫作的最大鼓勵
- 持續更新,未完待續…