溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

面向?qū)ο?property

發(fā)布時(shí)間:2020-06-29 04:42:36 來源:網(wǎng)絡(luò) 閱讀:298 作者:DevOperater 欄目:編程語言

1.property

1.1什么是property

property是一種特殊的屬性,訪問它會(huì)執(zhí)行一個(gè)函數(shù),然后返回值
特點(diǎn):
1.執(zhí)行函數(shù)時(shí)不需要obj.func()這樣調(diào)用,直接obj.func,像調(diào)用變量一樣調(diào)用函數(shù),就可以執(zhí)行一個(gè)函數(shù)
2.不能給其賦值
3.但是有@func.setter和@func.deleter裝飾器放在func上,可以實(shí)現(xiàn)對func的設(shè)置和刪除

例如:BMI值=體重(kg)÷身高^2(m)
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight / (self.height**2)

p1=People('egon',75,1.85)
print(p1.bmi)
例如:圓的周長和面積
import math
class Circle:
    def __init__(self,radius): #圓的半徑radius
        self.radius=radius

    @property
    def area(self):
        return math.pi * self.radius**2 #計(jì)算面積

    @property
    def perimeter(self):
        return 2*math.pi*self.radius #計(jì)算周長

c=Circle(10)
print(c.radius)
print(c.area) #可以向訪問數(shù)據(jù)屬性一樣去訪問area,會(huì)觸發(fā)一個(gè)函數(shù)的執(zhí)行,動(dòng)態(tài)計(jì)算出一個(gè)值
print(c.perimeter) #同上
'''
輸出結(jié)果:
314.1592653589793
62.83185307179586
'''
"這里的area和perimeter不能被賦值"
c.area=3 #為特性area賦值
'''
拋出異常:
AttributeError: can't set attribute
'''

1.2為什么使用property

將一個(gè)類的函數(shù)定義為特性后,對象再去使用的時(shí)候obj.name,根本無法察覺自己的name是執(zhí)行了一個(gè)函數(shù)計(jì)算出來的,這個(gè)property的使用方式遵循了統(tǒng)一訪問的原則

ps:面向?qū)ο蟮姆庋b有三種方式:
【public】
這種其實(shí)就是不封裝,是對外公開的
【protected】
這種封裝方式對外不公開,但對朋友(friend)或者子類(形象的說法是“兒子”,但我不知道為什么大家 不說“女兒”,就像“parent”本來是“父母”的意思,但中文都是叫“父類”)公開
【private】
這種封裝對誰都不公開

python并沒有在語法上內(nèi)置public,protected,private,在Java中會(huì)把所有數(shù)據(jù)設(shè)置為私有的,然后提供set和get方法去設(shè)置和獲取,在Python中可以通過property實(shí)現(xiàn)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Foo:
    def __init__(self,val):
        self.__NAME=val #將所有的數(shù)據(jù)屬性都隱藏起來

    @property
    def name(self):
        return self.__NAME #obj.name訪問的是self.__NAME(這也是真實(shí)值的存放位置)

    @name.setter
    def name(self,value):
        if not isinstance(value,str):  #在設(shè)定值之前進(jìn)行類型檢查
            raise TypeError('%s must be str' %value)
        self.__NAME=value #通過類型檢查后,將值value存放到真實(shí)的位置self.__NAME

    @name.deleter
    def name(self):
        raise TypeError('Can not delete')
f=Foo('egen')
print(f.name)

f.name="10"
print(f.name)

結(jié)果
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
egen
10

Process finished with exit code 0
f.name=10
結(jié)果
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
Traceback (most recent call last):
  File "E:/PythonProject/python-test/BasicGrammer/test.py", line 23, in <module>
    f.name=10
  File "E:/PythonProject/python-test/BasicGrammer/test.py", line 15, in name
    raise TypeError('%s must be str' %value)
TypeError: 10 must be str

Process finished with exit code 1
del f.name

結(jié)果
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
Traceback (most recent call last):
  File "E:/PythonProject/python-test/BasicGrammer/test.py", line 23, in <module>
    del f.name
  File "E:/PythonProject/python-test/BasicGrammer/test.py", line 20, in name
    raise TypeError('Can not delete')
TypeError: Can not delete

Process finished with exit code 1
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI