首頁 > 娛樂
python學習筆記1
由 李想530 發表于 娛樂2023-01-26
簡介(打印出sina的header)www
python sleep怎麼用
字典取鍵值對
當在字典中迴圈時,用
items()
方法可將關鍵字和對應的值同時取出
>>> knights = {‘gallahad’: ‘the pure’, ‘robin’: ‘the brave’}
>>> for k, v in knights。items():
。。。 print(k, v)
異常處理
try
…
except
語句有一個可選的
else 子句
,在使用時必須放在所有的 except 子句後面。對於在 try 子句不引發異常時必須執行的程式碼來說很有用
for arg in sys。argv[1:]:
try:
f = open(arg, ‘r’)
except OSError:
print(‘cannot open’, arg)
else:
print(arg, ‘has’, len(f。readlines()), ‘lines’)
f。close()
@property使用
Python內建的
@property
裝飾器就是負責把一個方法變成屬性呼叫的:
class
Student
(
object
):
@property
def
score
(
self
):
return
self
。
_score
@score
。
setter
def
score
(
self
,
value
):
if
not
isinstance
(
value
,
int
):
raise
ValueError
(
‘score must be an integer!’
)
if
value
<
0
or
value
>
100
:
raise
ValueError
(
‘score must between 0 ~ 100!’
)
self
。
_score
=
value
還可以定義只讀屬性,只定義getter方法,不定義setter方法就是一個只讀屬性:
class
Student
(
object
):
@property
def
birth
(
self
):
return
self
。
_birth
@birth
。
setter
def
birth
(
self
,
value
):
self
。
_birth
=
value
@property
def
age
(
self
):
return
2015
-
self
。
_birth
定製類
怎麼才能列印一個物件好看呢?只需要定義好
__str__()
方法,返回一個好看的字串就可以了
>>>
class
Student
(
object
):
。。。
def
__init__
(
self
,
name
):
。。。
self
。
name
=
name
。。。
def
__str__
(
self
):
。。。
return
‘Student object (name: %s)’
%
self
。
name
。。。
>>>
(
Student
(
‘Michael’
))
Student
object
(
name
:
Michael
)
直接敲變數不用
,打印出來的例項還是不好看:
>>>
s
=
Student
(
‘Michael’
)
>>>
s
<
__main__
。
Student
object
at
0x109afb310
>
再定義一個
__repr__()
。但是通常
__str__()
和
__repr__()
程式碼都是一樣的,所以,有個偷懶的寫法:
class
Student
(
object
):
def
__init__
(
self
,
name
):
self
。
name
=
name
def
__str__
(
self
):
return
‘Student object (name=%s)’
%
self
。
name
__repr__
=
__str__
iter
如果一個類想被用於
for 。。。 in
迴圈,類似list或tuple那樣,就必須實現一個
__iter__()
方法,該方法返回一個迭代物件,然後,Python的for迴圈就會不斷呼叫該迭代物件的
__next__()
方法拿到迴圈的下一個值,直到遇到
StopIteration
錯誤時退出迴圈。
我們以斐波那契數列為例,寫一個Fib類,可以作用於for迴圈:
class
Fib
(
object
):
def
__init__
(
self
):
self
。
a
,
self
。
b
=
0
,
1
# 初始化兩個計數器a,b
def
__iter__
(
self
):
return
self
# 例項本身就是迭代物件,故返回自己
def
__next__
(
self
):
self
。
a
,
self
。
b
=
self
。
b
,
self
。
a
+
self
。
b
# 計算下一個值
if
self
。
a
>
100000
:
# 退出迴圈的條件
raise
StopIteration
()
return
self
。
a
# 返回下一個值
非同步IO
asyncio
是Python 3。4版本引入的標準庫,直接內建了對非同步IO的支援。
asyncio
的程式設計模型就是一個訊息迴圈。我們從
asyncio
模組中直接獲取一個
EventLoop
的引用,然後把需要執行的協程扔到
EventLoop
中執行,就實現了非同步IO。
用
asyncio
實現
Hello world
程式碼如下:
import
asyncio
@asyncio
。
coroutine
def
hello
():
(
“Hello world!”
)
# 非同步呼叫asyncio。sleep(1):
r
=
yield
from
asyncio
。
sleep
(
1
)
(
“Hello again!”
)
# 獲取EventLoop:
loop
=
asyncio
。
get_event_loop
()
# 執行coroutine
loop
。
run_until_complete
(
hello
())
loop
。
close
()
@asyncio。coroutine
把一個generator標記為coroutine型別,然後,我們就把這個
coroutine
扔到
EventLoop
中執行。
hello()
會首先打印出
Hello world!
,然後,
yield from
語法可以讓我們方便地呼叫另一個
generator
。由於
asyncio。sleep()
也是一個
coroutine
,所以執行緒不會等待
asyncio。sleep()
,而是直接中斷並執行下一個訊息迴圈。當
asyncio。sleep()
返回時,執行緒就可以從
yield from
拿到返回值(此處是
None
),然後接著執行下一行語句。
把
asyncio。sleep(1)
看成是一個耗時1秒的IO操作,在此期間,主執行緒並未等待,而是去執行
EventLoop
中其他可以執行的
coroutine
了,因此可以實現併發執行。
我們用Task封裝兩個
coroutine
試試:
import
threading
import
asyncio
@asyncio
。
coroutine
def
hello
():
(
‘Hello world! (%s)’
%
threading
。
currentThread
())
yield
from
asyncio
。
sleep
(
1
)
(
‘Hello again! (%s)’
%
threading
。
currentThread
())
loop
=
asyncio
。
get_event_loop
()
tasks
=
[
hello
(),
hello
()]
loop
。
run_until_complete
(
asyncio
。
wait
(
tasks
))
loop
。
close
()
觀察執行過程:
Hello world! (<_MainThread(MainThread, started 140735195337472)>)
Hello world! (<_MainThread(MainThread, started 140735195337472)>)
(暫停約1秒)
Hello again! (<_MainThread(MainThread, started 140735195337472)>)
Hello again! (<_MainThread(MainThread, started 140735195337472)>)
由列印的當前執行緒名稱可以看出,兩個
coroutine
是由同一個執行緒併發執行的。
如果把
asyncio。sleep()
換成真正的IO操作,則多個
coroutine
就可以由一個執行緒併發執行。
我們用
asyncio
的非同步網路連線來獲取sina、sohu和163的網站首頁:
import
asyncio
@asyncio
。
coroutine
def
wget
(
host
):
(
‘wget %s。。。’
%
host
)
connect
=
asyncio
。
open_connection
(
host
,
80
)
reader
,
writer
=
yield
from
connect
header
=
‘GET / HTTP/1。0\r\nHost: %s\r\n\r\n’
%
host
writer
。
write
(
header
。
encode
(
‘utf-8’
))
yield
from
writer
。
drain
()
while
True
:
line
=
yield
from
reader
。
readline
()
if
line
==
b‘\r\n’
:
break
(
‘%s header > %s’
%
(
host
,
line
。
decode
(
‘utf-8’
)。
rstrip
()))
# Ignore the body, close the socket
writer
。
close
()
loop
=
asyncio
。
get_event_loop
()
tasks
=
[
wget
(
host
)
for
host
in
[
‘www。sina。com。cn’
,
‘www。sohu。com’
,
‘www。163。com’
]]
loop
。
run_until_complete
(
asyncio
。
wait
(
tasks
))
loop
。
close
()
執行結果如下:
wget www。sohu。com。。。
wget www。sina。com。cn。。。
wget www。163。com。。。
(等待一段時間)
(打印出sohu的header)
www。sohu。com header > HTTP/1。1 200 OK
www。sohu。com header > Content-Type: text/html
。。。
(打印出sina的header)
www。sina。com。cn header > HTTP/1。1 200 OK
www。sina。com。cn header > Date: Wed, 20 May 2015 04:56:33 GMT
。。。
(打印出163的header)
www。163。com header > HTTP/1。0 302 Moved Temporarily
www。163。com header > Server: Cdn Cache Server V2。0
。。。
可見3個連線由一個執行緒透過
coroutine
併發完成。