掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
Python是一個(gè)面向?qū)ο蟮恼Z(yǔ)言,但是因?yàn)閜ython語(yǔ)言的特性,我們大多的python程序員只是把它當(dāng)做一個(gè)工具,在我們項(xiàng)目的實(shí)際使用中除了使用Django框架以外,其他的都是使用python最基礎(chǔ)的方式,完全跟pythonic沒(méi)有一點(diǎn)關(guān)系,當(dāng)然主要還是因?yàn)槲覀兡芰μ?。面向?qū)ο笫菚?shū)寫(xiě)各種框架的基礎(chǔ),python的面向?qū)ο蟛粌H擁有通用面向?qū)ο蟮奶匦?,而且還擁有一些極其強(qiáng)大的特性,可以讓我們把它的便利性發(fā)揮到極致。本篇將詳細(xì)介紹Python 類(lèi)的成員、成員修飾符、類(lèi)的特殊成員。

類(lèi)的成員
類(lèi)的成員可以分為三個(gè)方面:字段、方法和屬性。
在定義一個(gè)類(lèi)以后,方法、屬性和靜態(tài)字段都是屬于類(lèi)的,在內(nèi)存中只保存一份,只有普通字段是屬于類(lèi)對(duì)象的,每個(gè)類(lèi)對(duì)象都會(huì)創(chuàng)建并保存一份。
我們可以將存儲(chǔ)區(qū)分為幾種:程序存儲(chǔ)區(qū)、全局存儲(chǔ)區(qū)、靜態(tài)存儲(chǔ)區(qū)、棧存儲(chǔ)區(qū)。
程序存儲(chǔ)區(qū): 我們所有的普通函數(shù)、類(lèi)函數(shù)、類(lèi)等程序所存儲(chǔ)的位置。
全局存儲(chǔ)區(qū):所有全局變量的存儲(chǔ)區(qū)。
靜態(tài)存儲(chǔ)區(qū):類(lèi)的靜態(tài)變量存儲(chǔ)區(qū)。
棧存儲(chǔ)區(qū):棧存儲(chǔ)區(qū)就是局部變量存儲(chǔ),所有的局部變量、類(lèi)對(duì)象等都存儲(chǔ)在這里。
字段
字段包括:普通字段和靜態(tài)字段,使用和定義都是不一樣的,其最本質(zhì)的區(qū)別就是內(nèi)存中保存的位置不同。
普通字段屬于對(duì)象
靜態(tài)字段屬于類(lèi)
class Demo: aa = "我是靜態(tài)字段" def __init__(self, name): self.bb = name def custom_func(self, name): self.cc = name
obj1 = Demo(11)
Demo.aa = 111111obj1.aa = 1obj1.custom_func(1111)
obj2 = Demo(22)
obj2.aa = 2Demo.aa = 222222obj2.custom_func(2222)
print("obj1.aa = ", obj1.aa)
print("obj1.bb = ", obj1.bb)
print("obj1.cc = ", obj1.cc)
print("Demo.aa = ", Demo.aa)
print("obj2.aa = ", obj2.aa)
print("obj2.bb = ", obj2.bb)
print("obj2.cc = ", obj2.cc)
print("Demo.aa = ", Demo.aa)
print("id(Demo.aa) = ", id(Demo.aa))
print("id(obj1.aa) = ", id(obj1.aa))
print("id(obj2.aa) = ", id(obj2.aa))
輸出
obj1.aa = 1 obj1.bb = 11 obj1.cc = 1111 Demo.aa = 222222 obj2.aa = 2 obj2.bb = 22 obj2.cc = 2222 Demo.aa = 222222 id(Demo.aa) = 4645988944 id(obj1.aa) = 4530158768 id(obj2.aa) = 4530158800
從上面我們可以看出,bb、cc為普通字段,每個(gè)類(lèi)獨(dú)有一份,相互不影響,而且需要使用類(lèi)對(duì)象訪問(wèn),而Demo.aa和obj.aa是不同的,我們看到obj.aa的行為與普通字段類(lèi)似,如果去掉obj1.aa=xx和obj2.aa=xx,那么obj1.aa和Demo.aa是相同的,在內(nèi)存中的地址也是相同的。這里涉及到python類(lèi)的另外一種特性-臨時(shí)屬性。
通常情況下我們都使用普通字段,當(dāng)一個(gè)變量在類(lèi)的所有對(duì)象中共同使用,而且數(shù)據(jù)共享的時(shí)候,我們就可以使用靜態(tài)字段。
方法
方法包括:普通方法、靜態(tài)方法和類(lèi)方法。他們的區(qū)別在于調(diào)用方式不同。
普通方法:由對(duì)象調(diào)用;包含一個(gè)self參數(shù);執(zhí)行普通方法時(shí),自動(dòng)將調(diào)用該方法的對(duì)象賦值給self;
類(lèi)方法:由類(lèi)調(diào)用; 包含一個(gè)cls參數(shù);執(zhí)行類(lèi)方法時(shí),自動(dòng)將調(diào)用該方法的類(lèi)復(fù)制給cls;
靜態(tài)方法:由類(lèi)調(diào)用;沒(méi)有默認(rèn)參數(shù);
class Foo:
FooName = "靜態(tài)字段"
def custom_func(self, name):
# 普通方法,至少包含一個(gè)self參數(shù)
print("普通方法") @classmethod
def class_func(cls, name):
# 類(lèi)方法,至少包含一個(gè)cls參數(shù)
print("類(lèi)方法") @staticmethod
def static_func(name):
# 靜態(tài)方法,沒(méi)有默認(rèn)參數(shù)
print("靜態(tài)方法")
f = Foo()# 調(diào)用普通方法f.custom_func("aaa")# 調(diào)用類(lèi)方法Foo.class_func("bbb")# 調(diào)用靜態(tài)方法Foo.static_func("ccc")
普通方法中可以直接使用對(duì)象的普通字段self.name
類(lèi)方法中可以直接使用靜態(tài)字段cls.FooName
靜態(tài)方法中不能直接使用普通字段和靜態(tài)字段
注意:靜態(tài)字段Foo.FooName可以在任意地方調(diào)用,包括以上三種場(chǎng)景內(nèi),如果在普通方法中也可以使用 self.FooName調(diào)用,前提是對(duì)象沒(méi)有同名的普通字段
屬性
上面我們已經(jīng)介紹了Python類(lèi)中的方法,那么屬性就非常簡(jiǎn)單了,因?yàn)镻ython中的屬性其實(shí)是普通方法的變種。
對(duì)于屬性,有以下兩個(gè)知識(shí)點(diǎn):
基本使用
兩種定義方式
class Foo:
def func(self):
pass @property
def prop(self):
print("屬性")
f = Foo()# 調(diào)用函數(shù)f.func()# 調(diào)用屬性f.prop
通過(guò)上面的例子,我們知道屬性有以下幾點(diǎn):
普通方法上添加@property裝飾器
有且只能有一個(gè)self參數(shù),不能額外增加參數(shù)
調(diào)用時(shí)不需要括號(hào)
我們?cè)谧鼍W(wǎng)頁(yè)數(shù)據(jù)展示的時(shí)候,頁(yè)面上顯示數(shù)據(jù)的數(shù)據(jù),不可能一次性把數(shù)據(jù)庫(kù)中的所有內(nèi)容都顯示在頁(yè)面上,一般都是通過(guò)分頁(yè)功能實(shí)現(xiàn),所以每次請(qǐng)求都會(huì)根據(jù)當(dāng)前頁(yè)數(shù)current_page和每頁(yè)顯示數(shù)量page_count來(lái)取出指定范圍的數(shù)據(jù)
class Pager: def __init__(self, current_page): # 當(dāng)前顯示的頁(yè)碼 self.current_page = current_page # 每頁(yè)默認(rèn)顯示數(shù)據(jù) self.per_items = 10 @property def start(self): return (self.current_page - 1) * self.per_items @property def end(self): return self.current_page * self.per_items pages = Pager(1) pages.start # 起始值pages.end # 結(jié)束值
屬性的兩種定義方式
屬性的定義有兩種方式:
裝飾器:在方法上應(yīng)用裝飾器
靜態(tài)字段:在類(lèi)中定義值為property對(duì)象的靜態(tài)字段
我們知道Python中的類(lèi)有經(jīng)典類(lèi)和新式類(lèi)之分,如果類(lèi)繼承自object,那么該類(lèi)是新式類(lèi),新式類(lèi)的屬性比經(jīng)典類(lèi)更豐富。但是現(xiàn)在都已經(jīng)使用python3了,而python3中默認(rèn)類(lèi)都繼承自object,所以python3中全是新式類(lèi)。
1. 裝飾器方式:普通方法加上@property裝飾器
class Goods: @property
def price(self):
print("@property") @price.setter
def price(self, val):
print("@price.setter: ", val) @price.deleter
def price(self):
print("@price.deleter")
obj = Goods()
obj.price # 自動(dòng)執(zhí)行@property修飾的price方法,并獲取方法的返回值obj.price = 100
#自動(dòng)執(zhí)行@price.setter修飾的price方法,并將100賦值給方法的參數(shù)del obj.price
# 自動(dòng)執(zhí)行@price.deleter修飾的price方法
2. 靜態(tài)字段方式,使用property創(chuàng)建靜態(tài)字段
property是一個(gè)類(lèi),在builtins.py文件中,初始化函數(shù):def __init__(self, fget=None, fset=None, fdel=None, doc=None),有四個(gè)參數(shù)
第一個(gè)參數(shù)fget是方法名,調(diào)用 對(duì)象.屬性 時(shí)自動(dòng)觸發(fā)執(zhí)行方法
第二個(gè)參數(shù)fset是方法名,調(diào)用 對(duì)象.屬性 = XXX 時(shí)自動(dòng)觸發(fā)執(zhí)行方法
第三個(gè)參數(shù)fdel是方法名,調(diào)用 del 對(duì)象.屬性 時(shí)自動(dòng)觸發(fā)執(zhí)行方法
第四個(gè)參數(shù)doc是字符串,調(diào)用 對(duì)象.屬性.doc ,此參數(shù)是該屬性的描述信息
class Foo: def __init__(self): self.price = 10 def get_price(self): return self.price # set函數(shù)必須有兩個(gè)參數(shù) def set_price(self, value): self.price = value def del_price(self): del self.price PRICE = property(get_price, set_price, del_price, "description Price") f = Foo() print(f.PRICE) # 自動(dòng)調(diào)用get_pricef.PRICE = 20 # 自動(dòng)調(diào)用set_priceprint(f.PRICE) # 自動(dòng)調(diào)用del_pricedel f.PRICE # 自動(dòng)調(diào)用description Price

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
微信二維碼
Copyright © 2002-2023 uogjgqi.cn 快上網(wǎng)建站品牌 QQ:244261566 版權(quán)所有 備案號(hào):蜀ICP備19037934號(hào)
微信二維碼
移動(dòng)版官網(wǎng)