python面向對象開發3 (內部類-構造-析構)魔術方法)


視頻地址

http://v.youku.com/v_show/id_XNDg3NjMzNDgw.html

復習一下,類屬性的用法。有的類屬性是在調用類方法后才建立的,類方法可以創建新的類屬性。

每次學習,代碼必須純手打。還好有vim,寫起來比較方便。嗯。不錯。

如果不運行類方法,那么有的類屬性,是沒有的。

這樣的程序結構如下。

#!/usr/bin/python
#coding:utf8
var4 = "全局變量"
class Milo():
    var1 = "類屬性,公有屬性var1"
    __var2 = "類的私有屬性 __var2"

    def fun(self):                        # 或者里面寫成 def fun(self,x,y,z): 里面傳入3個值。
        self.var2 = "對象的公有屬性var2"
        self.__var3 = "對象的私有屬性__var3"
        var4 = "函數 fun 的局部變量var4"
        print var4
        print self.__var3

    def other(self):
        print var4
        print self.__var3       # 這表示在運行類方法fun()之后,實例有了個
                                # self.__var3的變量。所以比較好

zou = Milo()
zou.fun()
# print zou.var4                # 如果不執行類方法fun()的話,那么將沒有zou.var4

zou.other()     # 單獨運行輸出self.__var3也不行,應該先運行類方法fun()之后

  魔術方法---


{內}{部}{類}--的構造


所謂內部類,就是在類內部定義的類,主要目的是為了更好的抽象現實世界。

內部類的距離:
汽車是個類,汽車的地盤,輪胎也可以抽象為類,將其定義到汽車類中,則形成了內部類,更好的描述汽車類,因為底盤,輪胎是汽車的一部分

一般不贊同使用內部類,會是程序結構復雜,但是理解內部類有助於理解模塊的調用。
很多模塊會使用內部類


魔術方法,魔術方法,不必實例化,當實例化類的時候,自動操作,
類似是這樣的,
class Milo():
    name = "csvt"
    def __str__(self): # 魔術方法 __XXOO__
    print "我是Milo實例化對象"

zou = Milo()
---------------運行的時候--------------
~ python cls_MoShuFangFa.py
我是Milo實例化對象
——————————————————————————————————————
說明在創建實例化對象的時候,就能自己執行一次!很magic!故稱作為魔術方法。


------------------魔術函數主要應用---------------

構造函數:
用於初始化類的內部狀態,Python提供的夠在函數是__init__(); 在實例化時候,自動執行的,__init__() 方法是可選的,如果不提供,python會給出一
個默認的__init__方法;
一般對數據的獲取需要自定義的get 和 set 方法


析構函數:
用於釋放對象占用的資源,python提供的析構函數是__del__();
__del__()也是可選的,如果不提供,則python會在后台提供默認析構函數
如果要顯示的調用析構函數,可以使用del關鍵字,方式如下:
del 對象名

更多關於魔術方法的介紹:http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/a-guide-to-pythons-magic-methods.html#python (一定要看)
~

請看下面的代碼案例:

#!/usr/bin/python
#coding:utf8

class Milo():

    class Test():               # 內部類和底下這些結構是平行的 
        var1 = "我是內部類"
                                # 定義后並不沖突,Milo類還是有這些屬性和方法
    name = "csvt"

    def __str__(self):          # 魔術方法,不必實例化,當實例化類的時候,自動操作
        return "我是Milo實例化的對象"

    def fun1(self):
        print self.name
        print "我是公有方法"
        self.__fun2()

    def __fun2(self):           # 這是一個內置方法
        print self.name
        print "我是私有方法"

#    @classmethod
    def classFun(self):
        print self.name
        print "我是類方法"

    classNewFun = classmethod(classFun)

#    @staticmethod
    def staticFun(self):
        print Milo.name
        print "我是靜態方法"

    staticNewFun = staticmethod(staticFun)


zou = Milo()            # 先創建一個實例
print zou               #輸出的結果是“我是Milo實例化的對象"

  內部類構造函數:

自己寫一個get 或者 set 方法,

用來自定義一些值。

1。常用  自己寫一個  set 方法,來設置類中屬性的值

class Moto():
    a = "This is a"
    b = "This is b"
    def set(self,x)                              # 設置了一個簡單的設置類內部變量的方法
        self.a = x

if __name__ == "__main__":

    obj = Moto()
    out = obj.set("How are you?")         # 自己定義的類中 get()方法,
    print out                     # 這樣的話就直接輸出“How are you?"這句話了。

 

#這是一個簡單的設置一個值的方法

2. 常用get方法   來獲取 類中屬性的值,或者需要的數據

class Moto():
    a = "This is a"
    b = "This is b"
    def get(self,x)

        if x == "a":

            return self.a

        else:

            return self.b

obj = Moto()

out = obj.get("a")         # 自己定義的類中 get()方法,
print out                     # 這樣的話就直接輸出“This is a"這句話了。

  

構造函數:

#!/usr/bin/python
#coding:utf8
name = "global"

class Ren:
    name = "人"
    hight = "一人高"
    wight = "一人重"
    __money = "我有10塊錢"		# 私有屬性
    __age = 30


    def __init__(self,n = "嬰兒"):	# 實例化的時候,就會被執行 
	print "初始化"
        self.name = n 
    
    def run(self):			# 類的方法定義,必須有一個行參
				#有人吧self,寫成cls 就是class
	print self.name			# 類中訪問自己類的屬性。
	print "跑步"

    def __lie(self):		# 私有方法只能被類內部方法使用
	print "我很欣賞你"

    def say(self):
	print "說話"
	self.__lie()		# 這個表示是調用的當前自己類里面的私有方法


    def get(self,x):		# 一般在調用私有屬性的時候,都是新建一個方法
				# 這里用了(self,x)目的是為了使用get("money")
				# 這樣的用法
	# return self.x	# 將私有屬性封裝起來
        if x == "money":
 	    return self.__money
        elif x == "age":
            return self.__age
	else:
	    return "請正確輸入"

    def set(self,x):		# 使用這個方法,我們用來修改內置屬性
	self.__age = x
	
    def moRi(self):
        return "世界末日"

    mr = classmethod(moRi)	# 類的方法,動態的,不實例化類,也能訪問這個方法
			# 從內存角度來說,節省內存,別的方法沒有加載


if __name__ == '__main__':      # 這表示如果被別人調用的話,將不執行
				# 被自己調用,執行

   zhangsan = Ren("張三")  # 把Ren類實例化,變成張三
   print zhangsan.name
   lisi = Ren("李四")
   print lisi.name
   wangwu = Ren()
print wangwu.name wangwu.__init__("王五") # 魔術函數也可以這樣用 print wangwu.name

  顯示的結果為:

alex@universe ~/python/OOP $ python cls_LeiDeGouZao.py 
初始化
張三
初始化
李四
初始化
嬰兒 初始化 王五

注意:王五上面有兩個初始化,原因是源代碼又執行了一次魔術函數 wangwu.__init__("王五")


~

釋放對象

現在我們需要結束程序了,這樣我們需要釋放一些內存,對象完成之后能自動釋放,(比如我們已經建立了一個mysql的對象)

在類中使用

def __del__(self):

    self.p.close()

    print "釋放資源完成"

##############通過上面的手段我們可以釋放盛放對象的內存

樣例如下:

 1 #!/usr/bin/python
 2 #coding:utf8
 3 name = "global"
 4 
 5 class Ren:
 6     name = ""
 7     hight = "一人高"
 8     wight = "一人重"
 9     __money = "我有10塊錢"        # 私有屬性
10     __age = 30
11 
12 
13     def __init__(self,n = "嬰兒"):    # 實例化的時候,就會被執行 
14         print "初始化中,請稍后……"
15         self.name = n 
16         self.p = file('/etc/passwd','r')    # 這是一個讀操作,初始化完成后,需要關閉
17     
18     def run(self):            # 類的方法定義,必須有一個行參
19                 #有人吧self,寫成cls 就是class
20         print self.name            # 類中訪問自己類的屬性。
21         print "跑步"
22 
23     def __lie(self):        # 私有方法只能被類內部方法使用
24         print "我很欣賞你"
25 
26     def say(self):
27         print "說話"
28         self.__lie()        # 這個表示是調用的當前自己類里面的私有方法
29 
30 
31     def get(self,x):        # 一般在調用私有屬性的時候,都是新建一個方法
32                 # 這里用了(self,x)目的是為了使用get("money")
33                 # 這樣的用法
34     # return self.x    # 將私有屬性封裝起來
35         if x == "money":
36             return self.__money
37         elif x == "age":
38             return self.__age
39         else:
40             return "請正確輸入"
41 
42     def set(self,x):        # 使用這個方法,我們用來修改內置屬性
43         self.__age = x
44     
45     def moRi(self):
46         return "世界末日"
47 
48     mr = classmethod(moRi)    # 類的方法,動態的,不實例化類,也能訪問這個方法
49             # 從內存角度來說,節省內存,別的方法沒有加載
50 
51     def __del__(self):        # 釋放函數,析構函數,當函數調用完成后自動釋放
52         self.p.close()        # p這個對象的從內存中釋放
53         print "釋放資源完成"
54 
55 
56 if __name__ == '__main__':      # 這表示如果被別人調用的話,將不執行
57                 # 被自己調用,執行
58 
59    zhangsan = Ren("張三")  # 把Ren類實例化,變成張三
60    print zhangsan.name

顯示結果如下:

alex@universe ~/python/OOP $ python cls_Lei_XiGouHanShu.py 
初始化中,請稍后……
張三
釋放資源完成
alex@universe ~/python/OOP $ 

 如果我們怕忘記

def __del__(self):

    self.p.close()         # 析構函數忘記加入類里面了 

 

我們可以使用python自帶的一個gc模塊,垃圾內存回收機制

[python 里面有一個自動的垃圾回收裝置。]
python采用垃圾回收機制來清理不再使用的對象;python提供gc模塊釋放不再使用的對象
python采用“引用計數”的算法方式來處理回收,即:當某個對象在其作用域的不再被其他對象引>用的時候,python就會自動清除對象;
python的函數collect()可以一次收集所有待處理的對象(gc.collect())

用法如下:

 1 #!/usr/bin/python
 2 #coding:utf8
 3 name = "global"
 4 import gc                   # 引入gc模塊,用來釋放內存垃圾
 5 class Ren:
 6     name = ""
 7     hight = "一人高"
 8     wight = "一人重"
 9     __money = "我有10塊錢"        # 私有屬性
10     __age = 30
11 
12 
13     def __init__(self,n = "嬰兒"):    # 實例化的時候,就會被執行 
14         print "初始化中,請稍后……"
15         self.name = n 
16         self.p = file('/etc/passwd','r')    # 這是一個讀操作,初始化完成后,需要關閉
17     
18     def run(self):            # 類的方法定義,必須有一個行參
19                 #有人吧self,寫成cls 就是class
20         print self.name            # 類中訪問自己類的屬性。
21         print "跑步"
22 
23     def __lie(self):        # 私有方法只能被類內部方法使用
24         print "我很欣賞你"
25 
26     def say(self):
27         print "說話"
28         self.__lie()        # 這個表示是調用的當前自己類里面的私有方法
29 
30 
31     def get(self,x):        # 一般在調用私有屬性的時候,都是新建一個方法
32                 # 這里用了(self,x)目的是為了使用get("money")
33                 # 這樣的用法
34     # return self.x    # 將私有屬性封裝起來
35         if x == "money":
36             return self.__money
37         elif x == "age":
38             return self.__age
39         else:
40             return "請正確輸入"
41 
42     def set(self,x):        # 使用這個方法,我們用來修改內置屬性
43         self.__age = x
44     
45     def moRi(self):
46         return "世界末日"
47 
48     mr = classmethod(moRi)    # 類的方法,動態的,不實例化類,也能訪問這個方法
49             # 從內存角度來說,節省內存,別的方法沒有加載
50 
51 #    def __del__(self):        # 釋放函數,析構函數,當函數調用完成后自動釋放
52 #    self.p.close()        # p這個對象的從內存中釋放
53 #    print "釋放資源完成"
54 
55 
56 if __name__ == '__main__':      # 這表示如果被別人調用的話,將不執行
57                 # 被自己調用,執行
58 
59    zhangsan = Ren("張三")  # 把Ren類實例化,變成張三
60    zhangsan.run()
61    zhangsan.run()
62    zhangsan.run()
63    zhangsan.run()
64    zhangsan.run()
65    zhangsan.run()
66    zhangsan.run()
67    print gc.collect()
68    lisi = Ren("李四")  # 把Ren類實例化,變成李四
69    lisi.run()
70    lisi.run()
71    lisi.run()
72    lisi.run()
73    lisi.run()
74    lisi.run()
75    print gc.collect() # 顯示一下到底還剩下多少內存垃圾,釋放完成了后,應該是0.這個做測試比較推薦

輸出的結果是:

alex@universe ~/python/OOP $ python cls_Lei_gc_ShiFang.py 
初始化中,請稍后……
張三
跑步
張三
跑步
張三
跑步
張三
跑步
張三
跑步
張三
跑步
張三
跑步
0
初始化中,請稍后……
李四
跑步
李四
跑步
李四
跑步
李四
跑步
李四
跑步
李四
跑步
0

  上面的顯示為0,說明所有的內存都已經被釋放完畢了。

import gc

gc.collect()

比較好用。

下一講,是常用內置方法

      已經講了,__init__ , __str__, __del__, 還要講一些


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM