Python 面向對象程序設計

Python 面向對象程序設計

image

1 面向過程編程

面向過程——Procedure Oriented,是一種以過程為中心的編程思想,它首先分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,在使用時依次調用,是一種基礎的順序的思維方式。面向過程開發方式是對計算機底層結構的一層抽象,它將程序分為數據和操縱數據的操作兩部分,其核心問題是數據結構和算法的開發和優化。

最典型的就是流水線,上一道工序完成後,後面的流程才能進行。

  • 面過程編程的特點:

    功能模塊化,代碼流程化

  • 優點:

    性能高,適合資源緊張、實時性強的場合

  • 缺點:

    不易復用和不易擴展

2 面向對象編程

面向對象編程——Object Oriented Programming,簡稱OOP,是一種程序設計思想。OOP把對象作為程序的基本單元,一個對象包含了數據和操作數據的函數。

面向對象的程序設計把計算機程序視為一組對象的集合,而每個對象都可以接收其他對象發過來的消息,並處理這些消息,計算機程序的執行就是一系列消息在各個對象之間傳遞。

在Python中,所有數據類型都可以視為對象,當然也可以自定義對象。自定義的對象數據類型就是面向對象中的類(Class)的概念。

3. 面向過程和面向對象的優缺點

面向對象 面向過程
特性 抽象、繼承、封裝、多態 功能模塊化,代碼流程化
優點 易維護、易復用、易擴展、低耦合 性能高,適合資源緊張、實時性強的場合
缺點 性能比面向過程低 沒有面向對象易維護、易復用、易擴展

4. 由淺入深了解面向對象

4.1 學生選課為例

"""
1, 要定義學生的信息: 姓名,性別,年齡,學校,所選課程
"""
# 學生的特徵:
student_name = 'Hans'
student_gender = 'M'
student_age = 20
shool = '社會大學'
student_course = []

# 學生的功能:選課
def course_selection_system(name, gender, age, shool, course):
    student_course.append(course)
    print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (name, gender, age, shool, student_course))
# 執行結果:
course_selection_system(student_name, student_gender, student_age, shool, "如何接受社會的毒打")
學生:Hans 性別:M 年齡:20 在社會大學 期間所選課程:['如何接受社會的毒打']


"""
2, 把學生的信息定義成一個字典
"""
student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社會大學',
    'student_course':[]
}

def course_selection_system(student, course):
    student1['student_course'].append(course)
    print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (student['student_name'], student['student_gender'], \
                                               student['student_age'], student['shool'], student['student_course']))
#執行結果:
course_selection_system(student1, "如何接受社會的毒打")
學生:Hans 性別:M 年齡:20 在社會大學 期間所選課程:['如何接受社會的毒打']

"""
3, 把選課的函數放到字典里, 某個學生要選課成功,裏面要包括他的特徵和技能,
這樣一個學生他的特徵和功能都有了
"""

def course_selection_system(student, course):
    student1['student_course'].append(course)
    print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (student['student_name'], student['student_gender'], \
                                               student['student_age'], student['shool'], student['student_course']))

student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社會大學',
    'student_course':[],
    'course_select':course_selection_system
}

student2 = {
    'student_name': 'Jack',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社會大學',
    'student_course':[],
    'course_select':course_selection_system
}
student1['course_select'](student1, "五塊錢如何花一星期")
student2['course_select'](student2, "如何接受社會的毒打")
#執行結果:
學生:Hans 性別:M 年齡:20 在社會大學 期間所選課程:['五塊錢如何花一星期']
學生:Jack 性別:M 年齡:20 在社會大學 期間所選課程:['如何接受社會的毒打'
                
# 這是一兩個學生,如果是十個,百個或更多都要手寫一遍???
# 這時就需要面向對象了。
"""
對象是什麼
	1. 程序中:
        	函數:盛放數據的容器
            對象:盛放數據和函數的容器
	2. 現實生活中:
        	一切皆對象
            對象:特徵與技能的結合體
"""

4.2 類和對象

"""
對象: 特徵與技能的結合體
類:一系列對象相似的特徵與相似的技能的結合體

站在不同的分類,劃分的分類不一定一樣

在程序中先有類再有對象。現實中先有對象,再有類
"""
# 把上面的程序 相同的部分拿出來,
student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社會大學',
    'student_course':[],
    'course_select':course_selection_system
}

student2 = {
    'student_name': 'Jack',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社會大學',
    'student_course':[],
    'course_select':course_selection_system
}
"""
這個程序中有哪些是相同的:
學校(shool)和選課功能(course_selection_system)
可以把這兩個功能提取出來
"""

student_public = {
    'shool':'社會大學',
    'course_select':course_selection_system
}
# 這個提取出來的公共的功能就是類,但在python中寫有專業的寫法:
class 類名():
    pass

# class為關鍵字 
# 類名一般首字母大寫
# 代碼:
class student_public():
    shool =  '社會大學'

    def course_selection_system(student, course):
        student1['student_course'].append(course)
        print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))

# 類在定義的時候會執行,這是與函數不同的地方(函數在定義時不會執行,只有在調用時執行)
# 查看類的名稱空間:
print(student_public.__dict__)
{'__module__': '__main__', 'shool': '社會大學', 'course_selection_system': <function student_public.course_selection_system at 0x000002ADBB6AA5F0>, '__dict__': <attribute '__dict__' of 'student_public' objects>, '__weakref__': <attribute '__weakref__' of 'student_public' objects>, '__doc__': None}

# 類的底層為字典
"""
類在定義時做了哪些:
	1. 類在定義時會立即執行
	2. 產生一個類的名稱空間,然後把類體里執行的數據都放到名稱空間里(__dict__返回的字典里)
	3. 把類的名稱空間綁定給__dict__
	
變量放到類裏面叫屬性
函數放到類裏面叫方法
"""

# 調用類
stu = student_public()
# 調用類從而產生對象。
# 調用類從而產生對象的過程,叫類的初始化

#查看對象的名稱空間
print(stu.__dict__)
# 執行結果:
{}  # 一個空字典

# 現在用Python的語法把類定義出來了。
# 但是學生自己獨有的特徵還沒有(自己的名字,自己的年齡等等),剛才看到了為空
# 給對象添加自己獨有的特徵
stu.__dict__['name'] = 'Hans'
stu.__dict__['gender'] = 'M'
stu.__dict__['age'] = 20
stu.__dict__['course'] = ['五塊錢如何花一星期','如何接受社會毒打']

print(stu.__dict__)
# 執行結果:
{'name': 'Hans', 'gender': 'M', 'age': 20, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}
# 對象的名稱空間為一個空字典,現在添加了一些key,所以也可以對它進行取值
print(stu.__dict__['name'])
Hans

#在Python中一般不使用這種方法賦值和取值,Python中的方法
# 添加
stu.name = 'Hans'
stu.gender = 'M'
stu.age = 20
stu.course = ['五塊錢如何花一星期','如何接受社會毒打']
# 取值
print(stu.__dict__)
print(stu.name)
# 執行結果:
{'name': 'Hans', 'gender': 'M', 'age': 20, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}
Hans
# 這種方法只能在對象種使用


# 上面的方法依然是很個學生對象都要寫一遍,所以這個方法也可以做成函數形式。
# 1. 定義一個類
class student_public():
    shool =  '社會大學'

    def course_selection_system(student, course):
        student['student_course'].append(course)
        print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))
#
# 實例化對象
stu1 = student_public()
# 定義函數
def init(name,gender,age,course):
    stu1.name = name
    stu1.gender = gender
    stu1.age = age
    stu1.course = course


init('hans', 'M',20,['五塊錢如何花一星期','如何接受社會毒打'])
print(stu1.__dict__)
# 執行結果:
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}

# init()函數中stu1為固定值,如果初始化一個學生,這個函數就不滿足了,所以stu1的位置也要傳參獲得
def init(student,name,gender,age,course):
    student.name = name
    student.gender = gender
    student.age = age
    student.course = course

stu1 = student_public()
stu2 = student_public()

init(stu1,'hans', 'M',20,['五塊錢如何花一星期','如何接受社會毒打'])
init(stu2,'jack', 'M',18,['五塊錢如何花一星期','如何接受社會毒打'])
print(stu1.__dict__)
print(stu2.__dict__)
# 執行結果:
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}
{'name': 'jack', 'gender': 'M', 'age': 18, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}
# 這樣比較相對比較完美了,但是每次都要手動調用init()這個方法,有沒有什麼方法可以自動執行init()
# 可以把它寫入到類裏面,不過要變形
class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社會大學'

    def course_selection_system(student, course):
        student['student_course'].append(course)
        print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))

print(student_public.__dict__)
stu1 = student_public()
# 執行結果:
TypeError: student_public.__init__() missing 4 required positional arguments: 'name', 'gender', 'age', and 'course'
# 提示要四個參數,現在給它傳四個參數:
stu1 = student_public('hans', 'M',20,['五塊錢如何花一星期','如何接受社會毒打'])
print(stu1.__dict__)
# 現在執行不會報錯
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五塊錢如何花一星期', '如何接受社會毒打']}

#  __init__()上面寫了五個參數,但是對象在調用的時候只讓寫四個,因為使用對象調用它會把自己當成第一個參數傳遞給函數。
# 在類中的方法,類和對象都可以調用,但是類在調用的時候,裏面寫了幾個參數就要傳幾個參數,但是使用對象時它把自己當成第一個參數傳過去,所以推薦使用對象調用

# Python中,因為方法中第一個參數為自己,所以把這個寫成self
class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.course = course

    shool = '社會大學'

    def course_selection_system(self, course):
        self['student_course'].append(course)
        print("學生:%s 性別:%s 年齡:%s 在%s 期間所選課程:%s" % (self['student_name'], self['student_gender'], \
                                                   self['student_age'], self['shool'], self['student_course']))

# 執行:
stu1 = student_public('hans', 'M', 20, '五塊錢如何花一星期')   # 實例化對象
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': '五塊錢如何花一星期'}

# 判斷一個
print(isinstance(stu1, student_public))
True

"""
調用類:
	1. 調用類(stu1 = student_public())會得到一個空對象,把這個空對象傳給student_public.__dict__
	2. 調用student_public.__dict__(空對象,'hans', 'M',20,'五塊錢如何花一星期')
	3. 得到一個初始化結果
	4. 在__init__里不能使用return 返回值,如果真要使用也只能返回None
"""

4.3 屬性的查找順序

類屬性(在類中定義的):

# 1, 查看類屬性
class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社會大學'
stu1 = student_public('hans', 'M',20,'五塊錢如何花一星期')
print(stu1.shool)

# 2, 增加一個類屬性
stu1.country = 'CN'
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': '五塊錢如何花一星期', 'country': 'CN'}

# 3, 修改類屬性
stu1.shool = '清華大學'
print(stu1.shool)
清華大學

# 4, 修改類屬性
del stu1.shool

對象屬性

class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社會大學'
stu1 = student_public('hans', 'M',20,'五塊錢如何花一星期')

# 1, 查看
print(stu1.name)
print(stu1.gender)
print(stu1.age)
hans
M
20

# 2, 修改
stu1.age = 18
print(stu1.age)
18

# 3,增加
stu1.result = '優'
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 18, 'course': '五塊錢如何花一星期', 'country': 'CN', 'result': '優'}

# 4, 刪除
del stu1.result
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 18, 'course': '五塊錢如何花一星期', 'country': 'CN'}

屬性查找順序

1. 先在對象中查找,如果對象中沒有則去類中查找
class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.course = course

    shool = '社會大學'
    
print(stu1.shool)  # 這個shool為類中定義的
社會大學
print(stu1.__dict__['shool']) # 這個會報錯,因為在對象stu1中根本沒有shool這個屬性,shool這個是類的屬性,直接這麼取是拿不到的,因為指定從對象stu1中的名稱空間中取,對象stu1中的名稱空間中根本沒有。
#所以使用點(.)的方式,如果對象中的名稱空間中沒有,它會去類的名稱空間中找。

class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.shool = "清華大學"
        self.course = course

    shool = '社會大學'
    
print(stu1.shool)  # 這個shool為對象中定義的
清華大學



5. 面向對象綁定方法

5.1 小案例:計算一共產生了多少個對象

class Count():
    count = 0

    def __init__(self, name):
        self.name = name
        Count.count +=1  # 統計次數

s1 = Count('Hello')
s2 = Count('World')
print(Count.count)
# 執行結果:
2

# 類屬性修改,所有對象都改。

# 還有一種寫法:
class Count():
    count = 0

    def __init__(self, name):
        self.name = name
        self.__class__.count +=1	# 統計次數 和Count.count +=1 一樣

s1 = Count('Hello')
s2 = Count('World')
print(Count.count)

5.2 綁定方法

綁定方法有兩種:

  • 綁定給對象

    class Students():
        def __init__(self,name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def printInfo(self):
            print("%s %s %s" % (self.name, self.age, self.gender))
    
    stu = Students("Hans", 18, 'M')
    stu.printInfo()
    
    # 把printInfo方法綁定給對象stu
    
  • 綁定給類

    IP = '192.168.1.123'
    PORT = 3306
    
    class Mysql():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    mysql = Mysql(IP, PORT)
    print(mysql.ip,mysql.port)
    # 執行結果:
    192.168.1.123 3306
    
    # 如果有多個需要寫多次。能不能把Mysql(IP, PORT)這個只寫一次
    # 可以把這個放到一個函數里
    
    IP = '192.168.1.123'
    PORT = 3306
    
    class Mysql():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        def tell(self):
            mysql = Mysql(IP, PORT)
            return mysql
    
    obj  = Mysql(IP, PORT)
    obj1 = obj.tell()
    print(obj1.ip,obj1.port)
    
    # 寫到函數里後,又有一個問題,mysql = Mysql(IP, PORT)現在是寫的MySQL的,如果換別的數據庫如redis,pg等是不是就不那麼靈活了。
    
    class Database():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        @classmethod
        def tell(cls):
            obj = cls(IP, PORT)
            return obj
    
    
    mysql  = Database.tell()
    print(mysql.ip, mysql.port)
    # 換個IP和端口
    IP = '192.168.1.111'
    PORT = 6379
    redis  = Database.tell()
    print(redis.ip, redis.port)
    # 執行結果:
    192.168.1.123 3306
    192.168.1.111 6379
    
    
    # @classmethod 這個裝飾器綁定給了類,以後類來調用,會自動把類名當成第一個參數傳過來(cls)
    # 這時調用的時候,使用類名調用
    # 如果即用到綁定對象,又用到綁定類,推薦使用綁定對象,因為在對象中可以使用__class__拿到類
    

5.3 靜態方法(非綁定方法)

import random
class Students():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def randnum(self):
        print(random.randint(1, 10))

info = Students("Hans", 18)
info.randnum()
info.randnum()
# 執行結果:
1
4

# 在 def randnum(self) 中根本沒有用到self,是不是可以不傳?
# 現在在類中如果不傳就會報錯(TypeError: Students.randnum() takes 0 positional arguments but 1 was given),所以可以使用 @staticmethod

import random
class Students():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    @staticmethod
    def randnum():
        print(random.randint(1, 10))

info = Students("Hans", 18)
info.randnum()
info.randnum()
# 執行結果:
4
9

6. 隱藏屬性

為什麼要隱藏屬性?

有些時間有些數據,只想讓內部看到,不想讓外部看到。

如何隱藏屬性

class Students():
    shool = '社會大學'
    def __init__(self,name,age):
        self.name = name
        self.age = age

stu1 = Students("Hans", 18)
print(stu1.shool)  
#shool是可以拿到的,如何把shool屬性隱藏掉

class Students():
    __shool = '社會大學'   # 只需要在屬性前面加兩個下劃線(__),只在前面加
    def __init__(self,name,age):
        self.name = name
        self.age = age

stu1 = Students("Hans", 18)
print(stu1.shool)
# 執行結果:
AttributeError: 'Students' object has no attribute 'shool'
    
print(stu1.__shool)
# 執行結果:
AttributeError: 'Students' object has no attribute '__shool'
# 就會發現shool這個不管用什麼方法都訪問不到了。
# 可以看一下它變成了什麼?
print(Students.__dict__)
{'__module__': '__main__', '_Students__shool': '社會大學', '__init__': <function Students.__init__ at 0x000001E5EC31A0E0>, '__dict__': <attribute '__dict__' of 'Students' objects>, '__weakref__': <attribute '__weakref__' of 'Students' objects>, '__doc__': None}
# 可以看到shool前面加了雙下劃線(__)後就變成: _Students__shool(_類名__屬性名)

# 現在在外面拿不到了,在內部是否可以拿到?
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool

stu1 = Students("Hans", 18)
print(stu1.get_shool())
# 執行結果:
社會大學
# 可以看到在內部可以拿到

# 其實如果外部要拿也能拿到:
stu1 = Students("Hans", 18)
print(stu1._Students__shool)  # 因為在類的名稱空間為_Students__shool,所以直接取這個就可以拿到
print(Students._Students__shool)
# 不但可以隱藏類中的屬性也可以隱藏方法和對象中的屬性,寫法都一樣,使用雙下劃線
# 對象屬性:
self.__name
#類中的方法:
def __get_shool(self):
#
# 在外部有方法拿到隱藏的屬性,是不是也可以修改? 正常的方法是改不了,可以在類中定義一個專門修改的函數
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self):
        self.__shool = "清華大學"
stu1 = Students("Hans", 18)
stu1.set_shool()
print(stu1.get_shool())

# 執行結果:
清華大學

# 更好的方法是給set_shool傳值
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self,shoolname):
        self.__shool = shoolname

stu1 = Students("Hans", 18)
stu1.set_shool("北京大學")
print(stu1.get_shool())
# 執行結果:
北京大學

# 還可以對修改的內容進行判斷,現在要修改的是學校名字,按目前寫的傳什麼值都可以,但有些類型不合適用在這個地方比如int類型,所以可以判斷一下。
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self,shoolname):
        # if type(shoolname) is not str: return 
        if not isinstance(shoolname, str): return
        self.__shool = shoolname

stu1 = Students("Hans", 18)
stu1.set_shool(123)  # 123  不是字符串,直接return返回,所以shool的值還是原來的
print(stu1.get_shool())
# 執行結果:
社會大學

"""
隱藏屬性發生了什麼?
	1, 在類定義階段發生了變化,如__shool變成了_Students__shool,也只有在定義階段發生變化,其他地方都不會發生變化
	2, 隱藏對外不對內
"""

image

7. property裝飾器

property是python的一種裝飾器,是用來修飾方法的。

上面的例子我們把一些不想對外公開的屬性隱蔽起來,而只是提供方法給用戶操作(查看get_shool和設置set_shool),在方法裏面,我們可以檢查參數的合理性等。

class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    def get_name(self):
        return  self.__name
	
    def set_name(self):
        self.__name="ABC"
        
stu = Students("Hans", 18)
print(stu.get_name())
stu.set_name()
print(stu.get_name())
# 執行結果:
Hans
ABC
# 我們要得到name必須要調用get_name方法,但正常我們取一個屬性直接使用.加屬性名就可以(stu.name),
# 但現在還要調用一個方法,如何實現即要隱藏屬性又要使用.屬性獲得值,就可以使用@property 
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):   # 為了更像stu.name這種方法,把方法名直接改為name
        return  self.__name

stu = Students("Hans", 18)
print(stu.name)
# 執行結果:
Hans

# @property 裝飾器會將 name() 方法轉化為一個具有相同名稱的只讀屬性的 "getter"

# 在修改的時候也要像查詢一樣,直接使得.屬性的方式
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):
        return  self.__name

    @name.setter
    def name(self,name):
        if not isinstance(name, str):
            print("必須為字符串")
            return
        self.__name= name

stu = Students("Hans", 18)
print(stu.name)   # Hans
stu.name = 123	# 必須為字符串,執行到了isinstance
print(stu.name) # Hans

# 修改為一個合法類型:
stu = Students("Hans", 18)
print(stu.name)  # Hans
stu.name = "XYZ"
print(stu.name)	# XYZ
# 可以看到已經修改
# 要使用這種方法,在定義時:
"""
	@property
    def name(self):     	1
        return  self.__name

    @name.setter  2
    def name(self,xxx) 3    
    這三個地方的名字一定要一致。
"""

# 刪除一個屬性
class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):
        return  self.__name

    @name.setter
    def name(self,name):
        if not isinstance(name, str):
            print("必須為字符串")
            return
        self.__name= name

    @name.deleter
    def name(self):
        del self.__name
        print("正在刪除%s" % self.__name)
stu = Students("Hans", 18)
del stu.name
print(stu.name)
# 執行結果:
正在刪除Hans

# 還有一種寫法,現在已經不常用了,即定義一個託管屬性

class Students():
    __shool = '社會大學'
    def __init__(self,name,age):
        self.__name = name
        self.age = age


    def get_name(self):
        return  self.__name


    def set_name(self,name):
        if not isinstance(name, str):
            print("必須為字符串")
            return
        self.__name= name


    def del_name(self):
        print("正在刪除%s" % self.__name)

    # 定義一個託管屬性 
    name = property(get_name, set_name, del_name) 


stu = Students("Hans", 18)
print(stu.name)   # 調用get_name 方法
stu.name = "XYZ"  # 調用set_name 方法
print(stu.name)
del stu.name	  # 調用del_name 方法

# 執行結果:
Hans
XYZ
正在刪除XYZ

property就是把方法偽裝成屬性

property詳細請看官網:

property

未完待續

Tags: