首頁 > 娛樂

python學習筆記1

由 李想530 發表于 娛樂2023-01-26

簡介(打印出sina的header)www

python sleep怎麼用

python學習筆記1

字典取鍵值對

當在字典中迴圈時,用

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

。。。

>>>

print

Student

‘Michael’

))

Student

object

name

Michael

直接敲變數不用

print

,打印出來的例項還是不好看:

>>>

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

():

print

“Hello world!”

# 非同步呼叫asyncio。sleep(1):

r

=

yield

from

asyncio

sleep

1

print

“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

():

print

‘Hello world! (%s)’

%

threading

currentThread

())

yield

from

asyncio

sleep

1

print

‘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

):

print

‘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

print

‘%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

併發完成。

Tags:__selfasynciocomloop