欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

python修飾器函數(shù)的簡(jiǎn)單介紹

什么是 NUMBA?

藍(lán)海大腦深度學(xué)習(xí)高性能液冷服務(wù)器研究人員表示:

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:申請(qǐng)域名網(wǎng)站空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、太和網(wǎng)站維護(hù)、網(wǎng)站推廣。

為了提高執(zhí)行速度,Numba 會(huì)在執(zhí)行前立即將 Python 字節(jié)代碼轉(zhuǎn)換為機(jī)器代碼。

Numba 可用于使用可調(diào)用的 Python 對(duì)象(稱為修飾器)來(lái)優(yōu)化 CPU 和 GPU 功能。修飾器是一個(gè)函數(shù),它將另一個(gè)函數(shù)作為輸入,進(jìn)行修改,并將修改后的函數(shù)返回給用戶。這種模組化可減少編程時(shí)間,并提高 Python 的可擴(kuò)展性。

Numba 還可與 NumPy 結(jié)合使用,后者是一個(gè)復(fù)雜數(shù)學(xué)運(yùn)算的開(kāi)源 Python 庫(kù),專為處理統(tǒng)計(jì)數(shù)據(jù)而設(shè)計(jì)。調(diào)用修飾器時(shí),Numa 將 Python 和/或 NumPy 代碼的子集轉(zhuǎn)換為針對(duì)環(huán)境自動(dòng)優(yōu)化的字節(jié)碼。它使用 LLVM,這是一個(gè)面向 API 的開(kāi)源庫(kù),用于以編程方式創(chuàng)建機(jī)器原生代碼。Numba 針對(duì)各種 CPU 和 GPU 配置,提供了多種快速并行化 Python 代碼的選項(xiàng),有時(shí)僅需一條命令即可。與 NumPy 結(jié)合使用時(shí),Numba 會(huì)為不同的數(shù)組數(shù)據(jù)類型和布局生成專用代碼,進(jìn)而優(yōu)化性能。

如何在Python Flask框架中運(yùn)行重復(fù)任務(wù)

Flask是一個(gè)使用Python編寫(xiě)的輕量級(jí)Web應(yīng)用框架,憑借更靈活、輕便、安全且容易上手的特性,成為企業(yè)常用的Python框架之一。在完成Web前端、Linux以及MySQL相關(guān)的課程之后,專業(yè)的杭州Python學(xué)習(xí)班都會(huì)講解Flask框架知識(shí),以下是整理的相關(guān)知識(shí)點(diǎn)。

Flask是一個(gè)基于Python開(kāi)發(fā)并且依賴jinja2模板和Werkzeug WSGI服務(wù)的一個(gè)微型框架,對(duì)于Werkzeug本質(zhì)是Socket服務(wù)端,其用于接收http請(qǐng)求并對(duì)請(qǐng)求進(jìn)行預(yù)處理,然后觸發(fā)Flask框架。開(kāi)發(fā)人員基于Flask框架提供的功能對(duì)請(qǐng)求進(jìn)行相應(yīng)的處理,并返回給用戶,如果要返回給用戶復(fù)雜的內(nèi)容時(shí),需要借助jinja2模板來(lái)實(shí)現(xiàn)對(duì)模板的處理,即:將模板和數(shù)據(jù)進(jìn)行渲染,將渲染后的字符串返回給用戶瀏覽器。

默認(rèn)情況下,F(xiàn)lask不包含數(shù)據(jù)庫(kù)抽象層、表單驗(yàn)證,或是其它任何已有多種庫(kù)可以勝任的功能。然而,F(xiàn)lask支持用擴(kuò)展來(lái)給應(yīng)用添加這些功能,如同是Flask本身實(shí)現(xiàn)的一樣。眾多的擴(kuò)展提供了數(shù)據(jù)庫(kù)集成、表單驗(yàn)證、上傳處理、各種各樣的開(kāi)放認(rèn)證技術(shù)等功能。

Flask框架的特點(diǎn):

1)Flask自由、靈活,可擴(kuò)展性強(qiáng),第三方庫(kù)的選擇面廣,開(kāi)發(fā)時(shí)可以結(jié)合自己最喜歡用的輪子,也能結(jié)合最流行最強(qiáng)大的Python庫(kù);

2)入門簡(jiǎn)單,即便沒(méi)有多少web開(kāi)發(fā)經(jīng)驗(yàn),也能很快做出網(wǎng)站;

3)非常適用于小型網(wǎng)站;

4)非常適用于開(kāi)發(fā)Web服務(wù)的API;

5)開(kāi)發(fā)大型網(wǎng)站無(wú)壓力,但代碼架構(gòu)需要自己設(shè)計(jì),開(kāi)發(fā)成本取決于開(kāi)發(fā)者的能力和經(jīng)驗(yàn)。

Flask框架運(yùn)行解釋

1.app = Flask(__name__)

創(chuàng)建Flask對(duì)象app,F(xiàn)lask類的構(gòu)造函數(shù)只有一個(gè)必須指定的參數(shù),即程序主模塊或包的名字。在大多數(shù)程序中,Python的__name__變量就是所需要的值。

2.@app.route('/')

web瀏覽器把請(qǐng)求發(fā)送給Web服務(wù)器,Web服務(wù)器再把請(qǐng)求發(fā)送給Flask程序?qū)嵗3绦驅(qū)嵗枰缹?duì)每個(gè)URL請(qǐng)求運(yùn)行哪些代碼,所以保存了一個(gè)URL到Python函數(shù)的映射關(guān)系。處理URL和函數(shù)之間的關(guān)系的程序稱為路由。在Flask程序中定義路由的最簡(jiǎn)便方式,是使用程序?qū)嵗峁┑腶pp.route修飾器,把修飾的函數(shù)注冊(cè)為路由。route()裝飾器告訴 Flask什么樣的URL 能觸發(fā)我們的函數(shù)。這和Java中的注釋有異曲同工之妙。修飾器是Python語(yǔ)言的標(biāo)準(zhǔn)特性,可以使用不同的方式修改函數(shù)的行為。慣常用法是使用修飾器把函數(shù)注冊(cè)為事件的處理程序。

3.def index():函數(shù)

index()函數(shù)放在@app.route('/')后面,所以就是把index()函數(shù)注冊(cè)為路由。如果部署程序的服務(wù)器域名為,在瀏覽器中訪問(wèn)后,會(huì)觸發(fā)服務(wù)器執(zhí)行index()函數(shù)。

4.@app.route('/user/')

同@app.route('/'),如果部署程序的服務(wù)器域名為,在瀏覽器中訪問(wèn)后,會(huì)觸發(fā)服務(wù)器執(zhí)行下方修飾函數(shù)。

5.app.run(debug=True)

程序?qū)嵗胷un方法啟動(dòng)Flask繼承Web服務(wù)器。

6.if __name__ == '__main__'

當(dāng)Python解釋器,讀py文件,它會(huì)執(zhí)行它發(fā)現(xiàn)的所有代碼。在執(zhí)行代碼之前,它會(huì)定義一些變量。例如,如果這個(gè)py文件就是主程序,它會(huì)設(shè)置__name__變量為"__main__"。如果這個(gè)py被引入到別的模塊,__name__會(huì)被設(shè)置為該模塊的名字。

python函數(shù)的幾種參數(shù)類型

#Python 2.5 #這個(gè)可以用修飾器來(lái)完成 #但是一般不會(huì)限制參數(shù)類型 #給你個(gè)思路: def argfilter(*types): def deco(func): #這是修飾器 def newfunc(*args): #新的函數(shù) if len(types)==len(args): correct = True for i in range(len(args)): if not isinstance(args[i], types[i]): #判斷類型 correct = False if correct: return func(*args) #返回原函數(shù)值 else: raise TypeError else: raise TypeError return newfunc #由修飾器返回新的函數(shù) return deco #返回作為修飾器的函數(shù) @argfilter(int, str) #指定參數(shù)類型 def func(i, s): #定義被修飾的函數(shù) print i, s #之后你想限制類型的話, 就這樣: #@argfilter(第一個(gè)參數(shù)的類名, 第二個(gè)參數(shù)的類名, ..., 第N個(gè)參數(shù)的類名) #def yourfunc(第一個(gè)參數(shù), 第一個(gè)參數(shù), ..., 第N個(gè)參數(shù)): # ... # #相當(dāng)于: #def yourfunc(第一個(gè)參數(shù), 第一個(gè)參數(shù), ..., 第N個(gè)參數(shù)): # ... #yourfunc = argfilter(第一個(gè)參數(shù)的類名, 第二個(gè)參數(shù)的類名, ..., 第N個(gè)參數(shù)的類名)(yourfunc)

python中修飾器是什么?

就是一個(gè)callable object。 它使python編程更加容易。

例如:

@dec

def A(args):

pass

它就等價(jià)于dec(A). 當(dāng)然還有帶參數(shù)的decorator。我就不舉例了。

python文檔里有這樣一句話。

A function definition may be wrapped by one or more decorator expressions. Decorator expressions are evaluated when the function is defined, in the scope that contains the function definition. The result must be a callable, which is invoked with the function object as the only argument. The returned value is bound to the function name instead of the function object. Multiple decorators are applied in nested fashion.

大概就是說(shuō)函數(shù)的定義可以用多個(gè)decorator。decorator就在函數(shù)定義時(shí)用函數(shù)作為參數(shù)調(diào)用,然后返回一個(gè)可調(diào)用對(duì)象。 所以寫(xiě)decorator的時(shí)候一定要返回一個(gè)可調(diào)用對(duì)象。

不知道你明白沒(méi)。

python中怎么設(shè)定函數(shù)形參的類型

直接寫(xiě)個(gè)名字就行。python的一切默認(rèn)都是對(duì)象,參數(shù)沒(méi)使用前,是沒(méi)有類型的。甚至函數(shù)寫(xiě)不寫(xiě)行參都無(wú)所謂。

如何正確地使用Python的屬性和描述符

關(guān)于@property裝飾器

在Python中我們使用@property裝飾器來(lái)把對(duì)函數(shù)的調(diào)用偽裝成對(duì)屬性的訪問(wèn)。

那么為什么要這樣做呢?因?yàn)锧property讓我們將自定義的代碼同變量的訪問(wèn)/設(shè)定聯(lián)系在了一起,同時(shí)為你的類保持一個(gè)簡(jiǎn)單的訪問(wèn)屬性的接口。

舉個(gè)栗子,假如我們有一個(gè)需要表示電影的類:

1

2

3

4

5

6

7

8

class Movie(object):

def __init__(self, title, description, score, ticket):

self.title = title

self.description = description

self.score = scroe

self.ticket = ticket

你開(kāi)始在項(xiàng)目的其他地方使用這個(gè)類,但是之后你意識(shí)到:如果不小心給電影打了負(fù)分怎么辦?你覺(jué)得這是錯(cuò)誤的行為,希望Movie類可以阻止這個(gè)錯(cuò)誤。 你首先想到的辦法是將Movie類修改為這樣:

Python

1

2

3

4

5

6

7

8

class Movie(object):

def __init__(self, title, description, score, ticket):

self.title = title

self.description = description

self.ticket = ticket

if score 0:

raise ValueError("Negative value not allowed:{}".format(score))

self.score = scroe

但這行不通。因?yàn)槠渌糠值拇a都是直接通過(guò)Movie.score來(lái)賦值的。這個(gè)新修改的類只會(huì)在__init__方法中捕獲錯(cuò)誤的數(shù)據(jù),但對(duì)于已經(jīng)存在的類實(shí)例就無(wú)能為力了。如果有人試著運(yùn)行m.scrore= -100,那么誰(shuí)也沒(méi)法阻止。那該怎么辦?

Python的property解決了這個(gè)問(wèn)題。

我們可以這樣做

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Movie(object):

def __init__(self, title, description, score):

self.title = title

self.description = description

self.score = score

self.ticket = ticket

@property

def score(self):

return self.__score

@score.setter

def score(self, score):

if score 0:

raise ValueError("Negative value not allowed:{}".format(score))

self.__score = score

@score.deleter

def score(self):

raise AttributeError("Can not delete score")

這樣在任何地方修改score都會(huì)檢測(cè)它是否小于0。

property的不足

對(duì)property來(lái)說(shuō),最大的缺點(diǎn)就是它們不能重復(fù)使用。舉個(gè)例子,假設(shè)你想為ticket字段也添加非負(fù)檢查。下面是修改過(guò)的新類:

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

class Movie(object):

def __init__(self, title, description, score, ticket):

self.title = title

self.description = description

self.score = score

self.ticket = ticket

@property

def score(self):

return self.__score

@score.setter

def score(self, score):

if score 0:

raise ValueError("Negative value not allowed:{}".format(score))

self.__score = score

@score.deleter

def score(self):

raise AttributeError("Can not delete score")

@property

def ticket(self):

return self.__ticket

@ticket.setter

def ticket(self, ticket):

if ticket 0:

raise ValueError("Negative value not allowed:{}".format(ticket))

self.__ticket = ticket

@ticket.deleter

def ticket(self):

raise AttributeError("Can not delete ticket")

可以看到代碼增加了不少,但重復(fù)的邏輯也出現(xiàn)了不少。雖然property可以讓類從外部看起來(lái)接口整潔漂亮,但是卻做不到內(nèi)部同樣整潔漂亮。

描述符登場(chǎng)

什么是描述符?

一般來(lái)說(shuō),描述符是一個(gè)具有綁定行為的對(duì)象屬性,其屬性的訪問(wèn)被描述符協(xié)議方法覆寫(xiě)。這些方法是__get__()、__set__()和__delete__(),一個(gè)對(duì)象中只要包含了這三個(gè)方法中的至少一個(gè)就稱它為描述符。

描述符有什么作用?

The default behavior for attribute access is to get, set, or delete the attribute from an object’s dictionary. For instance, a.x has a lookup chain starting witha.__dict__[‘x’], then type(a).__dict__[‘x’], and continuing through the base classes of type(a) excluding metaclasses. If the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined.—–摘自官方文檔

簡(jiǎn)單的說(shuō)描述符會(huì)改變一個(gè)屬性的基本的獲取、設(shè)置和刪除方式。

先看如何用描述符來(lái)解決上面 property邏輯重復(fù)的問(wèn)題。

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class Integer(object):

def __init__(self, name):

self.name = name

def __get__(self, instance, owner):

return instance.__dict__[self.name]

def __set__(self, instance, value):

if value 0:

raise ValueError("Negative value not allowed")

instance.__dict__[self.name] = value

class Movie(object):

score = Integer('score')

ticket = Integer('ticket')

因?yàn)槊枋龇麅?yōu)先級(jí)高并且會(huì)改變默認(rèn)的get、set行為,這樣一來(lái),當(dāng)我們?cè)L問(wèn)或者設(shè)置Movie().score的時(shí)候都會(huì)受到描述符Integer的限制。

不過(guò)我們也總不能用下面這樣的方式來(lái)創(chuàng)建實(shí)例。

a = Movie()

a.score = 1

a.ticket = 2

a.title = ‘test’

a.descript = ‘…’

這樣太生硬了,所以我們還缺一個(gè)構(gòu)造函數(shù)。

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class Integer(object):

def __init__(self, name):

self.name = name

def __get__(self, instance, owner):

if instance is None:

return self

return instance.__dict__[self.name]

def __set__(self, instance, value):

if value 0:

raise ValueError('Negative value not allowed')

instance.__dict__[self.name] = value

class Movie(object):

score = Integer('score')

ticket = Integer('ticket')

def __init__(self, title, description, score, ticket):

self.title = title

self.description = description

self.score = score

self.ticket = ticket

這樣在獲取、設(shè)置和刪除score和ticket的時(shí)候都會(huì)進(jìn)入Integer的__get__、__set__,從而減少了重復(fù)的邏輯。

現(xiàn)在雖然問(wèn)題得到了解決,但是你可能會(huì)好奇這個(gè)描述符到底是如何工作的。具體來(lái)說(shuō),在__init__函數(shù)里訪問(wèn)的是自己的self.score和self.ticket,怎么和類屬性score和ticket關(guān)聯(lián)起來(lái)的?

描述符如何工作

看官方的說(shuō)明

If an object defines both __get__() and __set__(), it is considered a data descriptor. Descriptors that only define __get__() are called non-data descriptors (they are typically used for methods but other uses are possible).

Data and non-data descriptors differ in how overrides are calculated with respect to entries in an instance’s dictionary. If an instance’s dictionary has an entry with the same name as a data descriptor, the data descriptor takes precedence. If an instance’s dictionary has an entry with the same name as a non-data descriptor, the dictionary entry takes precedence.

The important points to remember are:

descriptors are invoked by the __getattribute__() method

overriding __getattribute__() prevents automatic descriptor calls

object.__getattribute__() and type.__getattribute__() make different calls to __get__().

data descriptors always override instance dictionaries.

non-data descriptors may be overridden by instance dictionaries.

類調(diào)用__getattribute__()的時(shí)候大概是下面這樣子:

1

2

3

4

5

6

7

def __getattribute__(self, key):

"Emulate type_getattro() in Objects/typeobject.c"

v = object.__getattribute__(self, key)

if hasattr(v, '__get__'):

return v.__get__(None, self)

return v

下面是摘自國(guó)外一篇博客上的內(nèi)容。

Given a Class “C” and an Instance “c” where “c = C(…)”, calling “c.name” means looking up an Attribute “name” on the Instance “c” like this:

Get the Class from Instance

Call the Class’s special method getattribute__. All objects have a default __getattribute

Inside getattribute

Get the Class’s mro as ClassParents

For each ClassParent in ClassParents

If the Attribute is in the ClassParent’s dict

If is a data descriptor

Return the result from calling the data descriptor’s special method __get__()

Break the for each (do not continue searching the same Attribute any further)

If the Attribute is in Instance’s dict

Return the value as it is (even if the value is a data descriptor)

For each ClassParent in ClassParents

If the Attribute is in the ClassParent’s dict

If is a non-data descriptor

Return the result from calling the non-data descriptor’s special method __get__()

If it is NOT a descriptor

Return the value

If Class has the special method getattr

Return the result from calling the Class’s special method__getattr__.

我對(duì)上面的理解是,訪問(wèn)一個(gè)實(shí)例的屬性的時(shí)候是先遍歷它和它的父類,尋找它們的__dict__里是否有同名的data descriptor如果有,就用這個(gè)data descriptor代理該屬性,如果沒(méi)有再尋找該實(shí)例自身的__dict__,如果有就返回。任然沒(méi)有再查找它和它父類里的non-data descriptor,最后查找是否有__getattr__

描述符的應(yīng)用場(chǎng)景

python的property、classmethod修飾器本身也是一個(gè)描述符,甚至普通的函數(shù)也是描述符(non-data discriptor)

django model和SQLAlchemy里也有描述符的應(yīng)用

Python

1

2

3

4

5

6

7

8

9

10

11

12

class User(db.Model):

id = db.Column(db.Integer, primary_key=True)

username = db.Column(db.String(80), unique=True)

email = db.Column(db.String(120), unique=True)

def __init__(self, username, email):

self.username = username

self.email = email

def __repr__(self):

return 'User %r' % self.username

后記

只有當(dāng)確實(shí)需要在訪問(wèn)屬性的時(shí)候完成一些額外的處理任務(wù)時(shí),才應(yīng)該使用property。不然代碼反而會(huì)變得更加啰嗦,而且這樣會(huì)讓程序變慢很多。

網(wǎng)站題目:python修飾器函數(shù)的簡(jiǎn)單介紹
地址分享:http://www.chinadenli.net/article14/docdhge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)外貿(mào)建站網(wǎng)站改版App開(kāi)發(fā)做網(wǎng)站虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)