Python中面向对象的讲解(3)
1.私有屬性和私有方法
封裝的意義:
將屬性和方法放到一起做為一個整體,然后通過實例化對象來處理;
隱藏內部實現細節,只需要和對象及其屬性和方法交互就可以了;
對類的屬性和方法增加 訪問權限控制。
私有權限:在屬性名和方法名 前面 加上兩個下劃線 __
類的私有屬性 和 私有方法,都不能通過對象直接訪問,但是可以在本類內部訪問;
類的私有屬性 和 私有方法,都不會被子類繼承,子類也無法訪問;
私有屬性 和 私有方法 往往用來處理類的內部事情,不通過對象處理,起到安全作用。
私有屬性:
class Person(object):def __init__(self,name,age):self.name=nameself.__age=agep=Person('fei',22) print(p.name) print(p.__age)
私有方法:
類部調用私有屬性和私有方法
子類不能繼承父類私有屬性和方法
1). 私有屬性,可以在類內部通過self調用,但不能通過對象訪問
2). 私有方法,可以在類內部通過self調用,但不能通過對象訪問
3). 對象不能訪問私有權限的屬性和方法
4). 子類不能繼承父類私有權限的屬性和方法
5). Python中沒有像C++中 public 和 private, protected 這些關鍵字來區別公有屬性和私有屬性。
6). Python是以屬性命名方式來區分,如果在屬性和方法名前面加了2個下劃線’__’,則表明該屬性和方法是私有權限,否則為公有權限。
2.修改私有屬性的值
class Person(object):def __init__(self):self.__age=24def set_age(self,age):self.__age=agedef get_age(self):return self.__agep=Person() p.set_age(28) print(p.get_age())現代軟件開發中,通常會定義get_xxx()方法和set_xxx()方法來獲取和修改私有屬性值
get_xxx()方法–>返回私有屬性的值
set_xxx()方法–>接收參數,修改私有屬性的值
對象不能訪問私有權限的屬性和方法,可以通過訪問公有方法set_money()來修改私有屬性的值,可以通過訪問公有方法get_money()來獲取私有屬性的值
3.類屬性和實例屬性
類屬性就是類對象所擁有的屬性,它被所有類對象的實例對象所共有,在內存中只存在一個副本,這個和C++中類的靜態成員變量有點類似。對于公有的類屬性,可以通過類或者實例對象訪問
實例屬性只能通過對象來調用,類不能調用
類屬性:
class People(object):name = 'Tom' # 公有的類屬性__age = 12 # 私有的類屬性p = People()print(p.name) # 正確 print(People.name) # 正確 print(p.__age) # 錯誤,不能在類外通過實例對象訪問私有的類屬性 print(People.__age) # 錯誤,不能在類外通過類對象訪問私有的類屬性可以通過類或者實例對象調用
實例屬性(對象屬性)
class People(object):address = '山東' # 類屬性def __init__(self):self.name = 'xiaowang' # 實例屬性self.age = 20 # 實例屬性 p = People() p.age = 12 # 實例屬性 print(p.address) # 正確 print(p.name) # 正確 print(p.age) # 正確 print(People.address) # 正確 print(People.name) # 錯誤 print(People.age) # 錯誤可以通過實例化對象調用,類不能調用
通過實例(對象)去修改類屬性
class People(object):country = 'china' #類屬性 print(People.country) p = People() print(p.country) p.country = 'japan' print(p.country) # 實例屬性會屏蔽掉同名的類屬性 print(People.country) del p.country # 刪除實例屬性 print(p.country)對象修改類屬性,只對本對象有效果,對別的
對象沒有影響
4.類方法和靜態方法
類方法:
類方法是類對象所擁有的方法,需要用修飾器@classmethod來標識其為類方法,對于類方法,第一個參數必須是類對象,一般以cls作為第一個參數(當然可以用其他名稱的變量作為其第一個參數,但是大部分人都習慣以’cls’作為第一個參數的名字,就最好用’cls’了),能夠通過實例對象和類對象去訪問。
class People(object):# 類屬性age =18#類方法,用classmethod來進行修飾@classmethoddef get_country(cls):return cls.age p = People() print(p.get_country()) #可以用過實例對象引用 print(People.get_country()) #可以通過類對象引用 class People(object):# 類屬性age= 18#類方法,用classmethod來進行修飾@classmethoddef get_country(cls):return cls.age@classmethoddef set_country(cls,age):cls.age = age p = People() print(p.get_country()) #可以用過實例對象訪問 print(People.get_country()) #可以通過類訪問 p.set_country(23) print(p.get_country()) print(People.get_country()) p1 = People() print(p1.get_country())結果顯示在用類方法對類屬性修改之后,通過類對象和實例對象訪問都發生了改變(全部改變)
靜態方法:
需要通過修飾器@staticmethod來進行修飾,靜態方法不需要多定義參數,可以通過對象和類來訪問。
class People(object):country = 'china'@staticmethod#靜態方法def get_country():return People.country p = People() # 通過對象訪問靜態方法 print(p.get_country()) # 通過類訪問靜態方法 print(People.get_country())靜態方法中不需要額外定義參數,因此在靜態方法中引用類屬性的話,必須通過類實例對象來引用,調用靜態方法可以通過對象或者類調用
實例方法
實例方法中的第一個參數是self,只能通過對象來訪問。
class People(object):def selfmethod(self):print("我是實例方法") p = People() p.selfmethod() #People.selfmethod() #報錯實例方法中需要self參數,因此調用實例方法只能通過實例對象調用 也可以通過類調用但是一般不這樣用
總結:
類方法使用@classmethod裝飾,第一個參數為類(cls),調用時可以通過類的實例或者類本身來調用。
實例方法定義時第一個參數為類的一個實例(self),調用時必須通過實例調用。
靜態方法使用@staticmethod裝飾,調用時可以使用類的實例或者類本身來調用。
5.__new__方法
__new__和__init__的作用
class A(object):def __init__(self):print('init方法')def __new__(cls, *args, **kwargs):print('new方法')return object.__new__(cls) a=A()
總結:
1). __new__至少要有一個參數cls,代表要實例化的類,此參數在實例化時由Python解釋器自動提供
2). __new__必須要有返回值,返回實例化出來的實例,這點在自己實現__new__時要特別注意,可以return父類__new__出來的實例,或者直接是object的__new__出來的實例
3). __init__有一個參數self,就是這個__new__返回的實例,__init__在__new__的基礎上可以完成一些其它初始化的動作,__init__不需要返回值
4). 我們可以將類比作制造商,__new__方法就是前期的原材料購買環節,__init__方法就是在有原材料的基礎上,加工,初始化商品環節
6.單例模式
單例模式:永遠用一個對象得實例,避免新建太多實例浪費資源
實質:使用__new__方法新建類對象時先判斷是否已經建立過,如果建過就使用已有的對象
class Foo(object):instance = Nonedef __init__(self):self.name = 'alex'def __new__(cls):if Foo.instance:return Foo.instanceelse:Foo.instance = object.__new__(cls)return Foo.instance obj1 = Foo() obj2 = Foo() print(obj1,obj2)
福利
總結
以上是生活随笔為你收集整理的Python中面向对象的讲解(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中面向对象的讲解(2)
- 下一篇: Python单元测试之unittest