日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Python 從attribute到property詳解

瀏覽:100日期:2022-08-04 08:30:59

字面意思上的區(qū)別

Attribute與property, 都可翻譯成屬性. 雖然無論是在中文中還是英文中 它們的意思都幾乎一樣, 但仍有些許差別. Google了好幾下, 找到了一個(gè)看起來比較靠譜的解釋:

According to Webster, a property is a characteristic that belongs to a thing’s essential nature and may be used to describe a type or species.

An attribute is a modifier word that serves to limit, identify, particularize, describe, or supplement the meaning of the word it modifies.

簡單來說, property是類的本質(zhì)屬性, 可用于定義和描述一個(gè)類別或物種; attribute則是用于詳細(xì)說明它所描述的物體, 是物體的具體屬性.

例如: 人都有嘴巴. 有的人嘴巴很大, 嘴巴是人的property之一, 而大嘴巴只能說是部分人的attribute.

從這個(gè)意義上講, property是attribute的子集.

Python里的attribute與property

回到Python.

Attribute與property在Java中不作區(qū)分, 但在Python中有所不同. 下面是Fluent Python(Chapter 19)給出的(非正式)定義:

Python 從attribute到property詳解

接下來分別解釋.

attribute

所有的數(shù)據(jù)屬性(data attribute)與方法(method)都是attribute. 根據(jù)attribute的所有者, 可分為class attribute與instance attribute. class或instance的所有attribute都存儲(chǔ)在各自的__dict__屬性中.

例如:

# Python3class Foo(): name = ’Foo class attribute’ def fn(self): passprint(’class attribute:’, Foo.__dict__)print()foo = Foo()foo.name = ’foo instance attribute’print(’instance attribute:’, foo.__dict__)

輸出:

class attribute: {’fn’: <function Foo.fn at 0x7fd135ec8ea0>, ... , ’name’: ’Foo class attribute’}

instance attribute: {’name’: ’foo instance attribute’}

property

property是出于安全考慮用setter/getter方法替代data attribute, 例如, 只讀屬性與屬性值合法性驗(yàn)證.

只讀屬性

例如:

class Foo(): def __init__(self, name): self.name = namefoo = Foo(’I do not want to be changed’)print(’foo.name = ’, foo.name)foo.name = ’Unluckily, I can be changed’print(’foo.name = ’, foo.name)

輸出:

foo.name = I do not want to be changedfoo.name = Unluckily, I can be changed

在上面的代碼中, 假如我們只想將foo的name屬性暴露給外部讀取, 但并不想它被修改, 我們?cè)撛趺崔k? 之前在Python 定義只讀屬性中列出了兩種解決方案. 第一種方案:”通過私有屬性”, 其實(shí)就是用property替代attribute.

將上面的foo.name改寫成property:

class Foo(): def __init__(self, name): self.__name = name @property def name(self): return self.__namefoo = Foo(’I do not want to be changed’)print(’foo.name = ’, foo.name)foo.name = ’Luckily, I really can not be changed’

輸出:

foo.name = I do not want to be changed---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-69-101c96ba497e> in <module>() 9 foo = Foo(’I do not want to be changed’) 10 print(’foo.name = ’, foo.name)---> 11 foo.name = ’Luckily, I really can not be changed’AttributeError: can’t set attribute

有兩點(diǎn)需要注意:

foo.name確實(shí)已經(jīng)不能通過foo.name = ...來修改了, 即, foo.name已經(jīng)是只讀屬性.

將foo.name從attribute變成property之后, 它的訪問方式并沒有改變. 也就是說, 對(duì)外接口沒有改變. 這個(gè)優(yōu)點(diǎn)可以讓我們從容的寫代碼, 不用在一開始就糾結(jié)于是使用property還是attribute, 因?yàn)榭梢远际褂胊ttribute, 如果有需要, 以后可以在不影響外部代碼的前提下隨時(shí)修改. 而在Java里要做到這一點(diǎn)很難(如果可以做到的話).

屬性值合法性驗(yàn)證

在上面的例子中, foo.name只有g(shù)etter方法, 是只讀的, 但其實(shí)property也是可修改的, 只需要為它添加一個(gè)setter方法就行了. 那么問題就來了, 如果property也是可讀可改, 那為何要費(fèi)事將attribute改寫成property呢?

想象一個(gè)簡單的購物相關(guān)的業(yè)務(wù)場(chǎng)景. 一個(gè)Item代表用戶購買的一樣?xùn)|西, 主要有類別, 價(jià)格和數(shù)量屬性:

class Item(): def __init__(self, category, count, price): self.cat = category self.count = count self.price = price

正常的調(diào)用是類似于這樣的, 價(jià)格與數(shù)量都是正數(shù):

item = Item(’Bread’, 1, 10)

可是, 若價(jià)格或數(shù)量設(shè)置為負(fù)數(shù)也不會(huì)報(bào)錯(cuò):

item.price = -10item.count = -1invalid_item1 = Item(’Bread’, -1, 10)invalid_item2 = Item(’Bread’, 1, -10)

從語法上看, 這些語句都是合法的, 但從業(yè)務(wù)上看, 它們都是不合法的. 那么, 怎樣才能防止這種非法賦值呢? 一種解決方案是按照J(rèn)ava風(fēng)格, 實(shí)現(xiàn)一個(gè)Java式的setter方法, 通過item.set_price(price)設(shè)置price屬性, 然后在set_price方法里寫驗(yàn)證代碼. 這樣是可行的, 但不夠Pythonic. Python的風(fēng)格是讀與寫都通過屬性名進(jìn)行:

print(item.price)item.price = -10

這樣做的好處之前提到過: 將attribute改寫成property時(shí)不會(huì)改變對(duì)外接口. 那么, 如何在執(zhí)行item.price = -10時(shí)檢驗(yàn)-10的合法性呢? 最直白的方法是在__setattr__方法里設(shè)置攔截, 但很麻煩, 特別是當(dāng)需要驗(yàn)證的屬性很多時(shí).(不信的話可以參照Python 定義只讀屬性的方案二試試).

Python提供的最佳方案是通過property的setter方法:

class Item(): def __init__(self, category, count, price): self.__cat = category # attribute self.count = count # property self.price = price # property @property def cat(self): return self.__cat @property def count(self): return self.__dict__[’count’] @count.setter def count(self, value): if value < 0: raise ValueError(’count can not be minus: %r’%(value)) self.__dict__[’count’] = value @property def price(self): return self.__dict__[’price’] @price.setter def price(self, value): if value < 0: raise ValueError(’price can not be minus: %r’%(value)) self.__dict__[’price’] = value

之前合法的語句現(xiàn)在仍然可以正常運(yùn)行:

item = Item(’Bread’, 1, 10)item.price = 20item.count = 2print(item.price)

但下面的語句執(zhí)行時(shí)便會(huì)報(bào)錯(cuò)了:

item = Item(’Bread’, 1, -10)# oritem.price = -10

會(huì)報(bào)出同一個(gè)錯(cuò)誤:

---------------------------------------------------------------------------ValueErrorTraceback (most recent call last)<ipython-input-93-4fcbd1284b2d> in <module>()----> 1 item.price = -10<ipython-input-91-7546240b5469> in price(self, value) 27 def price(self, value): 28 if value < 0:---> 29 raise ValueError(’price can not be minus: %r’%(value)) 30 self.__dict__[’price’] = valueValueError: price can not be minus: -10

定義property的其他方式

@property中的property雖可被當(dāng)作修飾器來使用, 但它其實(shí)是一個(gè)class(具體API請(qǐng)參考文檔), 所以上面的代碼還可以改寫為:

class Item(): def __init__(self, category, count, price): self.__cat = category # attribute self.count = count # property self.price = price # property def get_cat(self): return self.__cat def get_count(self): return self.__dict__[’count’] def set_count(self, value): if value < 0: raise ValueError(’count can not be minus: %r’%(value)) self.__dict__[’count’] = value def get_price(self): return self.__dict__[’price’] def set_price(self, value): if value < 0: raise ValueError(’price can not be minus: %r’%(value)) self.__dict__[’price’] = value bill = property(get_bill) cat = property(get_cat) count = property(get_count, set_count) price = property(get_price, set_price)

功能上達(dá)到要求了, 可代碼本身看起來很冗長, 比Java中的getter/setter風(fēng)格還要長. 這時(shí)可以通過property factory來簡化代碼:

先定義可共用的property factory函數(shù):

def readonly_prop(storage_name): def getter(instance): return instance.__dict__[storage_name] return property(getter)def positive_mutable_prop(storage_name): def getter(instance): return instance.__dict__[storage_name] def setter(instance, value): if value < 0: raise ValueError(’%s can not be minus: %r’%(storage_name, value)) instance.__dict__[storage_name] = value return property(getter, setter)

然后, 之前的示例代碼可以簡化為:

class Item(): def __init__(self, category, count, price): self.__cat = category # attribute self.count = count # property self.price = price # property cat = readonly_prop(’__cat’) count = positive_mutable_prop(’count’) price = positive_mutable_prop(’price’)

這樣一來, 在保證代碼簡潔的前提下實(shí)現(xiàn)了訪問控制和合法性驗(yàn)證.

property不會(huì)被instance attribute覆蓋

之前在Python對(duì)象的屬性訪問過程一文中展示了attribute的解析過程, 從中知道class attribute可以被instance attribute覆蓋:

class Foo(): name = ’Foo’foo = Foo()foo.name = ’foo’codes = [’Foo.name’, ’foo.name’]for code in codes: print(code, ’=’, eval(code))

輸出為:

Foo.name = Foofoo.name = foo

但在property身上不會(huì)發(fā)生這種事情:

class Foo(): @property def name(self): return ’Foo’foo = Foo()foo.__dict__[’name’] = ’foo’# 已經(jīng)不能通過foo.name賦值了codes = [’Foo.name’, ’foo.name’]for code in codes: print(code, ’=’, eval(code))

輸出:

Foo.name = <property object at 0x7fd135e7ecc8>foo.name = Foo

至少可以看出兩點(diǎn):

1. 通過class Foo訪問Foo.name得到的是property對(duì)象, 而非property值.

2. 訪問 foo.name時(shí)返回的是Foo.name的property值. 究其原因, 是因?yàn)樵趯傩越馕鲞^程中, property的優(yōu)先級(jí)是最高的.

總結(jié)

1.Python的attribute與property不同:

attribute: data attribute + method

property: replace attribute with access control methods like getter/setter, for security reasons.

2.可以通過多種方式定義property:

@property

property(getter, setter)

property factory

3.property在屬性解析時(shí)的優(yōu)先級(jí)最高, 不會(huì)被instance attribute覆蓋.

以上這篇Python 從attribute到property詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
麻豆成全视频免费观看在线看| 国产精品流白浆在线观看| 日韩久久一区| 偷拍亚洲精品| 亚洲a级精品| 日韩一区二区三区精品 | 欧美激情视频一区二区三区免费 | 97久久亚洲| 久久精品999| 久久精品二区亚洲w码| 97精品资源在线观看| 国产精品主播| 超级白嫩亚洲国产第一| 国产一区二区三区不卡视频网站| 国产精品香蕉| 国际精品欧美精品| 欧美黄色网页| 中文字幕色婷婷在线视频| 最新中文字幕在线播放 | 久久亚洲美女| 欧美久久精品| 国产成人精品亚洲日本在线观看| 影音先锋久久| 久久久久伊人| 91久久国产| 国产亚洲字幕| 亚洲午夜视频| 国产精品久久| 香蕉精品999视频一区二区| 国产日韩欧美一区二区三区| 国产伦理一区| 亚洲激情婷婷| 毛片不卡一区二区| 亚洲一区欧美| 成人精品天堂一区二区三区| 亚洲三级观看| 蜜臀久久99精品久久一区二区| 深夜福利一区| 亚洲精品一区二区在线看| 国产欧美日韩一级| 中文一区一区三区免费在线观 | 青青伊人久久| 夜久久久久久| av资源中文在线| 日本午夜精品一区二区三区电影| 国产专区一区| 四虎8848精品成人免费网站 | 欧美日韩尤物久久| 国产精品视频首页| 日日夜夜免费精品视频| 激情欧美国产欧美| 999国产精品999久久久久久| 一区二区三区四区精品视频| 欧洲在线一区| 欧美sm一区| 在线手机中文字幕| 欧美国产小视频| 成人在线超碰| 国产精品99视频| 国产精久久一区二区| 日韩高清在线观看一区二区| 日韩欧美另类中文字幕| 在线观看一区| 日本特黄久久久高潮| 亚洲毛片一区| 国产精品久一| 日本久久精品| 国产精品毛片视频| 麻豆国产精品777777在线| 久久狠狠久久| 久久久免费人体| 老牛国内精品亚洲成av人片| 久久激五月天综合精品| 国产三级一区| 精品国产乱码久久久| 久久久精品网| 国产亚洲毛片| 日韩av一二三| 国产一区二区三区国产精品| 国产a亚洲精品| 久久精品观看| 亚洲我射av| 欧美视频一区| 久草免费在线视频| 快she精品国产999| 欧美aa在线视频| 精品在线91| 欧美亚洲tv| 色爱综合av| 欧美日韩一区自拍| 99精品视频在线| 国产美女久久| 婷婷综合网站| 日本黄色精品| 亚洲狼人精品一区二区三区| 久久99久久人婷婷精品综合| 美女少妇全过程你懂的久久| 日韩在线观看一区二区三区| 国产成人精选| 国产丝袜一区| 亚洲欧美高清| 亚洲人成精品久久久| 人人爱人人干婷婷丁香亚洲| 一区二区三区四区日韩| 群体交乱之放荡娇妻一区二区| 久久久夜夜夜| 伊人久久亚洲| 国产一区二区三区免费在线| 美女91精品| 日韩精品欧美激情一区二区| 国产精品一国产精品| 欧美日韩国产综合网| 国产日韩欧美一区| 一本色道精品久久一区二区三区| 欧美国产不卡| 国产伦一区二区三区| 亚洲激情另类| 欧美1区2区3区| 国产一区丝袜| 国产精品99视频| 久久97视频| 欧美精品99| 国产丝袜一区| 国产精品巨作av| 国产精品一区二区99| 久久av导航| 国产精品久久久久久久久免费高清 | 亚洲一区资源| 成人日韩在线| 天堂网在线观看国产精品| 99精品在线免费在线观看| 久久久国产精品一区二区中文| 成人片免费看| 国产综合精品| 噜噜噜久久亚洲精品国产品小说| 中文精品视频| 日韩精品国产精品| 欧美有码在线| 国产精品成人一区二区不卡| 国产精品免费大片| 精品久久免费| 亚洲国产专区校园欧美| 在线综合亚洲| 日韩一区精品| 欧美激情亚洲| 久久久久久久久丰满| 日韩午夜黄色| 日韩二区三区在线观看| 美女久久久精品| 精品一区在线| 久久国产视频网| 手机在线电影一区| 亚洲一区国产一区| 国产精品美女在线观看直播| 麻豆免费精品视频| 欧美aa国产视频| 欧美日韩亚洲一区| 激情久久五月| 国产精品香蕉| 日韩视频二区| 韩日一区二区| 亚洲精品乱码久久久久久蜜桃麻豆| 国产精品宾馆| 模特精品在线| 国产一区二区三区黄网站| 免费成人在线观看| 麻豆一区二区三| 综合亚洲视频| 欧美天堂亚洲电影院在线观看| 日韩精品一二三四| 久久青草久久| 日本一区二区免费高清| 日韩黄色免费网站| 亚洲免费精品| 精品成人免费一区二区在线播放| 国产探花一区在线观看| 天堂成人国产精品一区| av免费不卡国产观看| 久久99精品久久久野外观看| 亚洲免费观看高清完整版在线观| 精品日韩毛片| 高清日韩欧美| 久久精品伊人| 国产亚洲欧美日韩在线观看一区二区| 亚洲黄色免费看| 国产精品啊v在线| 国产精品调教视频| 欧美亚洲一区二区三区| 日韩在线麻豆| 亚洲欧美日韩在线观看a三区 | 国产日韩欧美三区| 日本午夜免费一区二区| 亚洲精品第一| 欧美一级二级视频| 欧美一区=区三区| 91精品国产自产精品男人的天堂| 国产成人免费精品| 亚洲天堂资源| 蜜桃精品视频| 国内自拍视频一区二区三区|