Python 面向對象編程之進階使用

咱們在http://www.javashuo.com/article/p-zmvsdabr-u.html中學習了面向對象的編程方法。如今學習他的進階用法。html

1. 靜態方法python

2. 類方法django

3. 屬性方法編程

4. 類的特殊功能方法ide

靜態方法、類方法以及屬性方法:咱們先定義一個類,在類裏定義一個方法工具

 1 class Person(object):
 2     def  __init__(self,name):
 3         self.name = name
 4        5 
 6     def eat(self,food):
 7         print("%s is eating %s"%(self.name,food))
 8 
 9 
10 peaple = Person("Jack")
11 peaple.eat("cake")
Jack is eating cake
運行結果

這個是常規的類的使用,一切正常,學習

而後咱們把方法前加一個@staticmethod,把eat()轉變成一個靜態方法,運行一下,程序報錯了!測試

TypeError: eat() missing 1 required positional argument: 'food'
運行結果

發現少了個參數,咱們把程序簡化一下,看看是怎麼回事!ui

1 class Person(object):
2     def  __init__(self,name):
3         self.name = name
4         self.__food = None
5     @staticmethod
6     def eat(self):
7         print(self.name)
8 peaple = Person("Jack")
9 peaple.eat()
TypeError: eat() missing 1 required positional argument: 'self'
運行結果

再改一下spa

1 class Person(object):
2     def  __init__(self,name):
3         self.name = name
4         self.__food = None
5     @staticmethod
6     def eat(name,food):
7         print("%s is eating %s"%(name,food))
8 peaple = Person("Jack")
9 peaple.eat("David","cake")
David is eating cake
運行結果

能夠發現,靜態方法沒法調用類裏的屬性了!

因此,靜態方法就是實際上已經跟類沒什麼關係了,也就是名義上歸類管理。在方法內沒法調用類或實例裏的任何屬性。還有個用法至關於類的工具包(高級語法,有機會再說!)。

咱們再看看類方法,在方法前加上@classmethod運行一下

1 class Person(object):
2     def  __init__(self,name):
3         self.name = name
4     @classmethod    #類方法
5     def eat(self,food):
6         print("%s is eating %s"%(self.name,food))
7 peaple = Person("Jack")
8 peaple.eat("cake")
AttributeError: type object 'Person' has no attribute 'name'
運行結果

提示沒有「name」的變量,爲何呢?咱們把name定義成類變量試一試。

1 class Person(object):
2     name = "Jeff"
3     def  __init__(self,name):
4         self.name = name
5     @classmethod
6     def eat(self,food):
7         print("%s is eating %s"%(self.name,food))
8 peaple = Person("Jack")
9 peaple.eat("cake")
Jeff is eating cake
運行結果

類變量只能訪問類變量,不能訪問實例變量。

屬性方法

1 class Person(object):
2     def __init__(self,name):
3         self.name = name
4     @property
5     def eat(self):
6         print("%s is eating"%self.name)
7 p1 = Person("Jack")
8 p1.eat  #這裏的p1.eat調用的是屬性,不是方法
Jack is eating
運行結果

在這個方法前加了@property,就把原來的方法改爲了屬性方法。在實例化後,不能用訪問方法的形式(p1.eat())去訪問,而要用屬性的形式(p1.eat)。

可是有個問題,若是在屬性方法裏有參數須要傳遞的話,就要用到裝飾器了!

 1 class Person(object):
 2     def __init__(self,name):
 3         self.name = name
 4         self.__food = None      #先定義個私有屬性
 5     @property
 6     def eat(self):
 7         print("%s is eating %s"%(self.name,self.__food))
 8     @eat.setter                 #定義裝飾器
 9     def eat(self,food):
10         print("set to food:",food)
11         self.__food = food
12 p1 = Person("Jack")
13 p1.eat
14 p1.eat = "bread"            #對屬性方法賦值
15 p1.eat
Jack is eating None
set to food: bread
Jack is eating bread
運行結果

完成效果,若是咱們想把屬性方法刪除,用通常的刪除方法是不行的

1 del p1.eat

這時候咱們必須在類裏從新定義個方法

 1 class Person(object):
 2     def __init__(self,name):
 3         self.name = name
 4         self.__food = None      #先定義個私有屬性
 5     @property
 6     def eat(self):
 7         print("%s is eating %s"%(self.name,self.__food))
 8     @eat.setter                 #定義裝飾器
 9     def eat(self,food):
10         print("set to food:",food)
11         self.__food = food
12     @eat.deleter                #刪除方法
13     def eat(self):
14         del self.__food
15         print("已刪除!")
16 p1 = Person("Jack")
17 p1.eat
18 p1.eat = "bread"            #對屬性方法賦值
19 p1.eat
20 del p1.eat                  #刪除屬性方法
21 p1.eat                      #從新調用測試一下
Jack is eating None
set to food: bread
Jack is eating bread
已刪除!
Traceback (most recent call last):
  File "D:/python/week7/屬性方法.py", line 45, in <module>
    p1.eat
  File "D:/python/week7/屬性方法.py", line 31, in eat
    print("%s is eating %s"%(self.name,self.__food))
AttributeError: 'Person' object has no attribute '_Person__food'
運行結果

 那有什麼用呢?幾個例子,航空公司都能提供航班狀態,而其餘的三方運營商須要調用這個值,顯而易見的是運營商不能修改航班狀態

 1 class Flight(object):
 2     def __init__(self,name):
 3         self.name = name
 4 
 5     def checking_status(self):
 6         print("checking flight %s status"%self.name)
 7     @property
 8     def flight_status(self):
 9         status = self.checking_status()
10         if status == 0:
11             print("flight is caceled!")
12         elif status == 1:
13             print("flight is arrived!")
14         elif status == 2:
15             print("flight has departured already!")
16         else:
17             print("cannot confirm the flight status,please check later!")
18 
19     @flight_status.setter    #航空公司返回航班的狀態關鍵字
20     def flight_status(self,status):
21         status_dic = {
22             0:'caceled',
23             1:'arrived',
24             2:'departured'
25         }
26 
27     @flight_status.deleter  #刪除該航班狀態
28     def flight_status(self):
29         print("status is deleted!")
30 f = Flight("MU2388")           #要查的航班編號
31 f.flight_status = 1             #航空公司每次只返回一個值描述出該航班狀態
32 f.flight_status                 #其餘的運營商直接訪問屬性的值,而不能改變其狀態 

 

如今來看一看一些類的特殊方法:

1.__doc__  獲取類的描述信息

1 # Author:Aaron
2 class People():
3     '''
4     該類描述了人類
5     '''
6     def func1(self):
7         pass
8 print(People.__doc__)
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/類的特殊成員.py
該類描述了人類
運行結果

在對類進行描述時,只能用‘’‘——’‘’來註釋,用#註釋時返回值爲None。而且__doc__能夠在不進行實例化時直接對類使用,也能夠對實例使用。

 2.__module__和__class__

1 from lib.aa import C
2 obj = C()
3 print(obj.__module__) #輸出lib.aa,即爲輸出該功能所屬模塊
4 print(obj.__class__)  #輸出lib.aa.C,即爲輸出該類

在大量調用模塊時,用這兩個方法能夠顯示調用的類是屬於那個模塊的。

3.__call__

在實例後加(),執行功能

1 class Dog():
2     def __call__(self, *args, **kwargs):
3         print("__call__的用法")
4 d1 = Dog()
5 d1()
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/類的特殊成員.py
__call__的用法
運行結果

在功能中,能夠傳遞各類參數。

4.__dict__查看類或對象中的全部成員

 1 class People():
 2     def __init__(self,name,age,sex):
 3         self.name = name
 4         self.age  = age
 5         self.sex  = sex
 6     def eat(self):
 7         pass
 8     def talk(self):
 9         pass
10 
11 p1= People("Jack",22,"male")
12 print(p1.__dict__)      #打印全部實例屬性,不包括類屬性
13 print(People.__dict__)  #打印全部類屬性,不包括實例屬性
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/類的特殊成員.py
{'name': 'Jack', 'age': 22, 'sex': 'male'}
{'__module__': '__main__', '__init__': <function People.__init__ at 0x00000243C1246510>, 'eat': <function People.eat at 0x00000243C1246598>, 'talk': <function People.talk at 0x00000243C1246620>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
運行結果

以一個字典的形式把類或實例的方法打印出來,做用是在程序運行之後,若是有新加的屬性,能夠用這個方式查看。

 5.__str__   能夠直接用print打印字符串

1 class People():
2     def __init__(self,name):
3         self.name = name
4     def __str__(self):
5         return 'obj:%s'%self.name
6 
7 p = People('Jeck')
8 print(p)
C:\Users\Aaron\Anaconda3\python.exe D:/python/week7/類的特殊成員.py
obj:Jeck
運行結果

 django中經常使用的用法,能夠用來返回實例。

6. __getitem__,__setitem__,__delitem__

能夠把一個字典封裝成一個實例(類),用字典的方式添加類的屬性等。而後控制字典的權限。用戶能夠訪問這個字典實際上是訪問了一個類,但能夠對用戶進行權限控制。

相關文章
相關標籤/搜索