1. 程式人生 > >python筆記(封裝(含類方法和靜態方法))

python筆記(封裝(含類方法和靜態方法))

一、封裝:
1、廣義上面向物件的封裝:程式碼的保護,面向物件的思想本身就是一種封裝
2、只讓自己的物件能呼叫自己類的方法
3、狹義上的封裝 – 面向物件三大特性
4、屬性和方法都藏起來,不讓你看見

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上雙下劃線後會變成私有屬性,只在類的內部可以使用
    def __get_pwd(self):         #加上雙下劃線後會變成私有方法
        return self.__passwd     #只要在類的內部使用私有屬性,就會自動帶上類名
long = Person('longlong','1234')  #long.passwd,long.__passwd都調不到
print(long.__dict__)
print(long._Person__passwd)     #_long.Person__passwd可以調到,但是是你在投機取巧的方式下知道的方式
print(long.get_pwd())

輸出結果:

{‘name’: ‘longlong’, ‘_Person__passwd’: ‘1234’}
1234
1234

(1)所有的私有 都是在變數的左邊加上雙下劃線
物件的私有屬性
類的私有方法
類中的靜態私有屬性
所有的私有的都不能在類的外部使用

class Room:
    def __init__(self,name,length,wideth):
        self.name = name
        self.__length = length
        self.__wideth = wideth
    def set_name(self,newName):
        if type(newName) is str and newName.isdigit() == False:
            self.__name = newName
    def get_name(self):
        return self.__name
    def area(self):
        return self.__length*self.__wideth
long = Room('龍龍',10,10)
print(long.area())
long.set_name('2')
print(long.get_name())

輸出結果:

100
Traceback (most recent call last):
File “D:/Python/python_txt/GUI進度條/GUI.py”, line 1258, in
print(long.get_name())
File “D:/Python/python_txt/GUI進度條/GUI.py”, line 1252, in get_name
return self.__name
AttributeError: ‘Room’ object has no attribute ‘_Room__name’

2、假設父類的私有屬效能被子類呼叫會用到私有的這個概念的場景
(1).隱藏起一個屬性,不想讓類的外部呼叫
(2).我想保護這個屬性,不能讓屬性隨意被改變
(3).我想保護這個屬性不被子類繼承

@property:把類的方法偽裝成一種屬性

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def perimeter(self):
        return 2*pi*self.r
    @property
    def area(self):
        return pi*self.r**2

c1 = Circle(5)
print(c1.area)
print(c1.perimeter)

輸出結果:

78.53981633974483
31.41592653589793

class Person:
    def __init__(self,name,high,weight):
        self.name = name
        self.high = high
        self.weight = weight
    @property
    def bmi(self):
        return self.weight/self.high**2
long = Person('龍',1.83,75)
print(long.bmi)

輸出結果:

22.395413419331717

 class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):                    #一般不能有引數
        return  self.__name + 'sb'
    @name.setter                    #實現對隱藏物件修改,只能傳一個引數
    def name(self,new_name):
        self.__name = new_name

geng= Person('耿')
print(geng.name)
geng.name = '娃'
print(geng.name)

耿sb
娃sb

class Goods:
discount = 0.8
def __init__(self,name,price):
    self.name = name
    self.__price = price
@property
def price(self):
    return self.__price*Goods.discount
apple = Goods('蘋果',5)
print(apple.price)

4.0

@屬性的檢視 修改 刪除

class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):
        return self.__name
    @name.deleter
    def name(self):           #刪除
        del self.__name
    @name.deleter
    def name(self,new_name):  #修改
        self.__name = new_name
geng = Person('耿娃')
print(geng.name)
del geng.name
geng.name('娃')
print(geng.name)

輸出結果:

耿娃
Traceback (most recent call last):
File “D:/Python/python_txt/GUI進度條/GUI.py”, line 1333, in
print(geng.name)
File “D:/Python/python_txt/GUI進度條/GUI.py”, line 1326, in name
return self.__name
AttributeError: ‘Person’ object has no attribute ‘_Person__name’

3、classmethod #類方法
@當這個方法的燥作只涉及靜態屬性的時候,就應該使用class_method來裝飾這個方法

class Goods:
    __discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price*Goods.__discount
    @classmethod
    def change_discount(cls,new_discount): #cls代表這個類
        cls.__discount = new_discount
apple = Goods('蘋果',5)
print(apple.price)
Goods.change_discount(0.5)
print(apple.price)

輸出結果:

4.0
2.5

4、staticmethod #靜態方法
在完全面向物件的程式中,如果一個的數既和物件沒有關係也和類沒有關係那麼就用staticmethod將這個函式變成一個靜態方法

class Login:
    def __init__(self,name,password):
        self.name = name
        self.pwd  = password
    def login(self):
        pass
    @staticmethod
    def get_usr_pwd():                 #沒有預設引數,就像函式一樣
        usr = input('使用者名稱:')
        pwd = input('密碼:')
        Login(usr,pwd)
Login.get_usr_pwd()