1. 程式人生 > 其它 >學習python,從入門到放棄(26)

學習python,從入門到放棄(26)

學習python,從入門到放棄(26)

動態方法與靜態方法

  • 動態方法

    繫結給物件的方法,第一個引數必須是例項物件,該引數名一般約定為 self ,通過它來傳遞例項的屬性和方法。

    class Student:
        def run(self):
            print(self)
    
    
    # 用繫結給物件的方法:有幾個引數就需要傳幾個引數
    Student.run(123)
    # 物件呼叫繫結給物件的方法:會自動將物件當做第一個引數傳入
    obj1 = Student()
    obj1.run()
    

    繫結給類的方法,使用裝飾器 @classmethod 。第一個引數必須是當前類物件,該引數名一般約定為cls

    ,通過它來傳遞類的屬性和方法。

    class Student:
        @classmethod
        def eat(cls):
            print(cls)
    
    
    # 類呼叫繫結給類的方法:會自動將類當做第一個引數傳入
    print(Student)  # <class '__main__.Student'>
    Student.eat()  # <class '__main__.Student'>
    # 物件呼叫繫結給類的方法:也不需要傳參 會講產生該物件的類自動當做第一個引數傳入
    obj1 = Student()
    obj1.eat()  # <class '__main__.Student'>
    
  • 靜態方法

    使用裝飾器@staticmethod。引數隨意,沒有selfcls引數,但是方法體中不能使用類或例項的任何屬性和方法。

    class Student:
        @staticmethod
        def speak(a):
            print(a)
    
    
    # 1.普普通通的函式:無論誰來調 都必須傳固定的引數個數
    # 類呼叫靜態方法:要自己傳值
    Student.speak(123)
    # 物件呼叫靜態方法:要自己傳值
    obj1 = Student()
    obj1.speak(321)
    

面向物件的三大特性之一:繼承

面向物件有三大特性,分別是繼承、封裝和多型,其中最重要的就是繼承。

現實生活中繼承是用來描述人與人之間資源的從屬關係,在python中也是差不多,面向物件中繼承是用來描述類與類之間資料的從屬關係。

繼承的目的是通過繼承可以減少程式碼冗餘,提升開發效率,同樣也支援多繼承。

我們將被繼承的類稱為:父類或者基類,繼承別人的類稱為:子類或者派生類。在python中一個類可以同時繼承多個父類,任何類都可以是父類,因此語法與建立任何其他類相同。

class A(B):  
    pass
class A(B,C,D):
    pass

繼承的本質由上往下直接獲取資源。在面向物件程式設計中,其實類和父類的主要功能都是用來減少程式碼冗餘的。物件是資料與功能的結合體,而類又是多個物件相同資料和功能的結合體,父類又是多個類相同資料和功能的結合體。

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
class Teacher(Person):
    def teach(self):
        print(f'{self.name}老師正在講課')
class Student(Person):
    def study(self):
        print(f'{self.name}學生正在學習')
stu1 = Student('jason', 18, 'male')

名字的查詢順序

  • 不繼承的情況下

    名字的查詢順序是先從物件自己的名稱空間中查詢,沒有則去類裡面的名稱空間查詢,但是要注意設定值的情況下是在自身的名稱空間中新增或者修改資料。

  • 單繼承的情況下

    先從物件自己的名稱空間中查詢,沒有擇取產生物件的類中查詢,如果還沒有並且類有父類則去父類中查詢,以此往復下去。

  • 多繼承的情況下

    在非菱形繼承的情況下,父類中名字的查詢順序就是按照繼承時從左往右依次查詢,如果多個父類還有分類 那麼遵循"深度優先"。

    菱形繼承的情況下,父類中名字的查詢順序就是按照繼承時從左往右依次查詢,如果多個父類還有分類 那麼遵循"廣度優先"。

名字的查詢順序永遠都是,先從當前物件自身開始查詢。

派生類

如果自己寫的子類需要使用父類的方法 並且還需要基於該方法做擴充套件,這樣的子類我們稱之為派生類,派生類的本質還是子類,使用我們依舊可以使用 super() 來實現。

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Teacher(Person):
    def __init__(self, name, age, gender, level, salary):
        # 用了Person類裡面的__init__方法之後
        # super(Teacher,self).__init__(name,age,gender)  # 子類呼叫父類的方法 完整語法
        super().__init__(name, age, gender)  # 子類呼叫父類的方法 精簡語法
        # 自己還要新增一個額外的東西
        self.level = level
        self.salary = salary


class Student(Person):
    def __init__(self, name, age, gender, stu_id, class_id):
        # 用了Person類裡面的__init__方法之後
        super().__init__(name, age, gender)
        # 自己還要新增一個額外的東西
        self.stu_id = stu_id
        self.class_id = class_id


t1 = Teacher('jason', 18, 'male', '滿級', 3.1)
s1 = Student('kevin', 28, 'female', 1302010201, 2)
print(t1.__dict__)
print(s1.__dict__)

派生功能前瞻

class MyClass(list):
    def append(self, args):
        if args == 123:
            print('數字123不能追加')
            return
        super(MyClass, self).append(args)


obj1 = MyClass()
obj1.append(333)
obj1.append(222)
obj1.append(123)
print(obj1)