99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀Python面向?qū)ο缶幊讨械念惡蛯ο髮W(xué)習(xí)教程
Python面向?qū)ο缶幊讨械念惡蛯ο髮W(xué)習(xí)教程
2018-02-11
收藏

Python面向?qū)ο缶幊讨械念惡蛯ο髮W(xué)習(xí)教程

Python中一切都是對象。類提供了創(chuàng)建新類型對象的機制。這篇教程中,我們不談類和面向?qū)ο蟮幕局R,而專注在更好地理解Python面向?qū)ο缶幊躺?。假設(shè)我們使用新風(fēng)格的python類,它們繼承自object父類。

定義類

class 語句可以定義一系列的屬性、變量、方法,他們被該類的實例對象所共享。下面給出一個簡單類定義:

classAccount(object):
  num_accounts=0
  
  def__init__(self, name, balance):
   self.name=name
   self.balance=balance
   Account.num_accounts+=1
  
  defdel_account(self):
   Account.num_accounts-=1
  
  defdeposit(self, amt):
   self.balance=self.balance+amt
  
  defwithdraw(self, amt):
   self.balance=self.balance-amt
  
  definquiry(self):
   returnself.balance

類定義引入了以下新對象:

類對象
    實例對象
    方法對象

類對象

程序執(zhí)行過程中遇到類定義時,就會創(chuàng)建新的命名空間,命名空間包含所有類變量和方法定義的名稱綁定。注意該命名空間并沒有創(chuàng)建類方法可以使用的新局部作用域,因此在方法中訪問變量需要全限定名稱。上一節(jié)的Account類演示了該特性;嘗試訪問num_of_accounts變量的方法需要使用全限定名稱Account.num_of_accounts,否則,如果沒有在__init__方法中使用全限定名稱,會引發(fā)如下錯誤:


classAccount(object):
 num_accounts=0
  
 def__init__(self, name, balance):
  self.name=name
  self.balance=balance
  num_accounts+=1
  
 defdel_account(self):
  Account.num_accounts-=1
  
 defdeposit(self, amt):
  self.balance=self.balance+amt
  
 defwithdraw(self, amt):
  self.balance=self.balance-amt
  
 definquiry(self):
  returnself.balance
  
>>> acct=Account('obi',10)
Traceback (most recent call last):
 File"python", line1,in<module>
 File"python", line9,in__init__
UnboundLocalError: local variable'num_accounts'referenced before assignment

類定義執(zhí)行的最后,會創(chuàng)建一個類對象。在進入類定義之前有效的那個作用域現(xiàn)在被恢復(fù)了,同時類對象被綁定到類定義頭的類名上。

先偏離下話題,你可能會問如果創(chuàng)建的類是對象,那么類對象的類是什么呢?。與一切都是對象的python哲學(xué)一致,類對象確實有個類,即python新風(fēng)格類中的type類。



>>>type(Account)
<class'type'>

讓你更迷惑一點,Account類型的類型是type。type類是個元類,用于創(chuàng)建其他類,我們稍后教程中再介紹。

類對象支持屬性引用和實例化。屬性通過標(biāo)準(zhǔn)的點語法引用,即對象后跟句點,然后是屬性名:obj.name。有效的屬性名是類對象創(chuàng)建后類命名空間中出現(xiàn)的所有變量和方法名。例如:



>>> Account.num_accounts
>>>0
>>> Account.deposit
>>> <unbound method Account.deposit>

類實例化使用函數(shù)表示法。實例化會像普通函數(shù)一樣無參數(shù)調(diào)用類對象,如下文中的Account類:

>>> Account()


類對象實例化之后,會返回實例對象,如果類中定義了__init__方法,就會調(diào)用,實例對象作為第一個參數(shù)傳遞過去。這個方法會進行用戶自定義的初始化過程,比如實例變量的初始化。Account類為例,賬戶name和balance會被設(shè)置,實例對象的數(shù)目增加1。
實例對象

如果類對象是餅干切割刀,餅干就是實例化類對象的結(jié)果。實例對象上的全部有效操作為對屬性、數(shù)據(jù)和方法對象的引用。
方法對象

方法對象和函數(shù)對象類似。如果x是Account類的實例,x.deposit就是方法對象的例子。方法定義中有個附加參數(shù),self。self指向類實例。為什么我們需要把實例作為參數(shù)傳遞給方法?方法調(diào)用能最好地說明:



>>> x=Account()
>>> x.inquiry()
10

實例方法調(diào)用時發(fā)生了什么?你應(yīng)該注意到x.inquiry()調(diào)用時沒有參數(shù),雖然方法定義包含self參數(shù)。那么這個參數(shù)到底發(fā)生了什么?

特殊之處在于方法所作用的對象被作為函數(shù)的第一個參數(shù)傳遞過去。在我們的例子中,對x.inquiry()的調(diào)用等價于Account.f(x)。一般,調(diào)用n參數(shù)的方法等同于將方法的作用對象插入到第一個參數(shù)位置。

python教程上講:

當(dāng)引用的實例屬性不是數(shù)據(jù)屬性時,就會搜索類。如果名稱表示一個合法的函數(shù)對象,實例對象和函數(shù)對象將會被打包到一個抽象對象,即方法對象中。包含參數(shù)列表的方法對象被調(diào)用時,將會根據(jù)實例對象和參數(shù)列表創(chuàng)建一個新的參數(shù)列表,然后函數(shù)對象將會使用新的參數(shù)列表被調(diào)用。

這適用于所有的實例方法對象,包括__init__方法。self參數(shù)其實不是一個關(guān)鍵字,任何有效的參數(shù)名都可以使用,如下Account類定義所示:



classAccount(object):
 num_accounts=0
  
 def__init__(obj, name, balance):
  obj.name=name
  obj.balance=balance
  Account.num_accounts+=1
  
 defdel_account(obj):
  Account.num_accounts-=1
  
 defdeposit(obj, amt):
  obj.balance=obj.balance+amt
  
 defwithdraw(obj, amt):
  obj.balance=obj.balance-amt
  
 definquiry(obj):
  returnobj.balance
  
>>> Account.num_accounts
>>>0
>>> x=Account('obi',0)
>>> x.deposit(10)
>>> Account.inquiry(x)
>>>10

靜態(tài)和類方法

類中定義的方法默認(rèn)由實例調(diào)用。但是,我們也可以通過對應(yīng)的@staticmethod和@classmethod裝飾器來定義靜態(tài)或類方法。
靜態(tài)方法

靜態(tài)方式是類命名空間中的普通函數(shù)。引用類的靜態(tài)方法返回的是函數(shù)類型,而不是非綁定方法類型:



classAccount(object):
 num_accounts=0
  
 def__init__(self, name, balance):
  self.name=name
  self.balance=balance
  Account.num_accounts+=1
  
 defdel_account(self):
  Account.num_accounts-=1
  
 defdeposit(self, amt):
  self.balance=self.balance+amt
  
 defwithdraw(self, amt):
  self.balance=self.balance-amt
  
 definquiry(self):
  return"Name={}, balance={}".format(self.name,self.balance)
  
 @staticmethod
 deftype():
  return"Current Account"
  
>>> Account.deposit
<unbound method Account.deposit>
>>> Account.type
<functiontypeat0x106893668>

使用@staticmethod裝飾器來定義靜態(tài)方法,這些方法不需要self參數(shù)。靜態(tài)方法可以更好地組織與類相關(guān)的代碼,也可以在子類中被重寫。
類方法

類方法由類自身來調(diào)用,而不是實例。類方法使用@classmethod裝飾器定義,作為第一個參數(shù)被傳遞給方法的是類而不是實例。



importjson
  
classAccount(object):
 num_accounts=0
  
 def__init__(self, name, balance):
  self.name=name
  self.balance=balance
  Account.num_accounts+=1
  
 defdel_account(self):
  Account.num_accounts-=1
  
 defdeposit(self, amt):
  self.balance=self.balance+amt
  
 defwithdraw(self, amt):
  self.balance=self.balance-amt
  
 definquiry(self):
  return"Name={}, balance={}".format(self.name,self.balance)
  
 @classmethod
 deffrom_json(cls, params_json):
    params=json.loads(params_json)
  returncls(params.get("name"), params.get("balance"))
  
 @staticmethod
 deftype():
  return"Current Account"

類方法一個常見的用法是作為對象創(chuàng)建的工廠。假如Account類的數(shù)據(jù)格式有很多種,比如元組、json字符串等。由于Python類只能定義一個__init__方法,所以類方法在這些情形中就很方便。以上文Account類為例,我們想根據(jù)一個json字符串對象來初始化一個賬戶,我們定義一個類工廠方法from_json,它讀取json字符串對象,解析參數(shù),根據(jù)參數(shù)創(chuàng)建賬戶對象。另一個類實例的例子是dict.fromkeys 方法,它從一組鍵和值序列中創(chuàng)建dict對象。
Python特殊方法

有時我們希望自定義類。這需要改變類對象創(chuàng)建和初始化的方法,或者對某些操作提供多態(tài)行為。多態(tài)行為允許定制在類定義中某些如+等python操作的自身實現(xiàn)。Python的特殊方法可以做到這些。這些方法一般都是__*__形式,其中*表示方法名。如__init__和__new__來自定義對象創(chuàng)建和初始化,__getitem__、__get__、__add__、__sub__來模擬python內(nèi)建類型,還有__getattribute__、__getattr__等來定制屬性訪問。只有為數(shù)不多的特殊方法,我們討論一些重要的特殊方法來做個簡單理解,python文檔有全部方法的列表。
進行對象創(chuàng)建的特殊方法

新的類實例通過兩階段過程創(chuàng)建,__new__方法創(chuàng)建新實例,__init__初始化該實例。用戶已經(jīng)很熟悉__init__方法的定義;但用戶很少定義__new__方法,但是如果想自定義類實例的創(chuàng)建,也是可以的。
屬性訪問的特殊方法

我們可以通過實現(xiàn)以下方法來定制類實例的屬性訪問。



classAccount(object):
 num_accounts=0
  
 def__init__(self, name, balance):
  self.name=name
  self.balance=balance
  Account.num_accounts+=1
  
 defdel_account(self):
  Account.num_accounts-=1
  
 def__getattr__(self, name):
  return"Hey I dont see any attribute called {}".format(name)
  
 defdeposit(self, amt):
  self.balance=self.balance+amt
  
 defwithdraw(self, amt):
  self.balance=self.balance-amt
  
 definquiry(self):
  return"Name={}, balance={}".format(self.name,self.balance)
  
 @classmethod
 deffrom_dict(cls, params):
  params_dict=json.loads(params)
  returncls(params_dict.get("name"), params_dict.get("balance"))
  
 @staticmethod
 deftype():
  return"Current Account"
  
x=Account('obi',0)

    __getattr__(self, name)__:這個方法只有當(dāng)name既不是實例屬性也不能在對象的類繼承鏈中找到時才會被調(diào)用。這個方法應(yīng)當(dāng)返回屬性值或者引發(fā)AttributeError異常。例如,如果x是Account類的實例,嘗試訪問不存在的屬性將會調(diào)用這個方法。



>>> acct=Account("obi",10)
>>> acct.number
Hey I dont seeanyattribute called number

注意如果 __getattr__引用不存在的實例屬性,可能會發(fā)生死循環(huán),因為__getattr__方法不斷被調(diào)用。

2.__setattr__(self, name, value)__:這個方法當(dāng)屬性賦值發(fā)生時調(diào)用。__setattr__將會把值插入到實例屬性字典中,而不是使用self.name=value,因為它會導(dǎo)致遞歸調(diào)用的死循環(huán)。

3.__delattr__(self, name)__:del obj發(fā)生時調(diào)用。

4.__getattribute__(self, name)__:這個方法會被一直調(diào)用以實現(xiàn)類實例的屬性訪問。
類型模擬的特殊方法

對某些類型,Python定義了某些特定語法;比如,列表和元組的元素可以通過索引表示法來訪問,數(shù)值可以通過+操作符來進行加法等等。我們可以創(chuàng)建自己的使用這些特殊語法的類,python解釋器遇到這些特殊語法時就會調(diào)用我們實現(xiàn)的方法。我們在下面用一個簡單的例子來演示這個特性,它模擬python列表的基本用法。

classCustomList(object):
  
 def__init__(self, container=None):
  # the class is just a wrapper around another list to
  # illustrate special methods
  ifcontainerisNone:
   self.container=[]
  else:
   self.container=container
  
 def__len__(self):
  # called when a user calls len(CustomList instance)
  returnlen(self.container)
  
 def__getitem__(self, index):
  # called when a user uses square brackets for indexing
  returnself.container[index]
  
 def__setitem__(self, index, value):
  # called when a user performs an index assignment
  ifindex <=len(self.container):
   self.container[index]=value
  else:
   raiseIndexError()
  
 def__contains__(self, value):
  # called when the user uses the 'in' keyword
  returnvalueinself.container
  
 defappend(self, value):
  self.container.append(value)
  
 def__repr__(self):
  returnstr(self.container)
  
 def__add__(self, otherList):
  # provides support for the use of the + operator
  returnCustomList(self.container+otherList.container)

上面,CustomList是個真實列表的簡單包裝器。我們?yōu)榱搜菔緦崿F(xiàn)了一些自定義方法:

__len__(self):對CustomList實例調(diào)用len()函數(shù)時被調(diào)用。

>>> myList=CustomList()
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>>len(myList)
4

2.__getitem__(self, value):提供CustomList類實例的方括號索引用法支持:


>>> myList = CustomList()
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>> myList[3]
4

3.__setitem__(self, key, value):當(dāng)對CustomList類實例上self[key]賦值時調(diào)用。    
>>> myList = CustomList()
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>> myList[3] = 100
4
>>> myList[3]
100

4.__contains__(self, key):成員檢測時調(diào)用。如果包含該項就返回true,否則false。
    
>>> myList = CustomList()
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>> 4 in myList
True

5.__repr__(self):當(dāng)用print打印self時調(diào)用,將會打印self的對象表示。
     
>>> myList = CustomList()
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>> print myList
[1, 2, 3, 4]

6.__add__(self, otherList):使用+操作符來計算兩個CustomList實例相加時調(diào)用。    
>>> myList = CustomList()
>>> otherList = CustomList()
>>> otherList.append(100)
>>> myList.append(1)
>>> myList.append(2)
>>> myList.append(3)
>>> myList.append(4)
>>> myList + otherList + otherList
[1, 2, 3, 4, 100, 100]
上面的例子演示了如何通過定義某些特殊類方法來定制類行為??梢栽赑ython文檔中查看這些自定義方法的完整列表。


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }