[015]Python面向對象_基礎_全棧基礎

您好!此筆記的文本和代碼以網盤形式分享於文末!

因個人能力有限,錯誤處歡迎大家交流和指正!基礎部分內容簡單,但多且零散!

#!/usr/bin/env python

# -*- coding:utf-8 -*-

"""

面向對象:

"""

"""

類(Class):

    用來描述具有相同的屬性和方法的對象的集合。

    它定義了該集合中每個對象所共有的屬性和方法。

    對象是類的實例。

class 類名:

    '類的文檔字符串'

    類體

"""

# # 創建一個類

# class Data:

#     pass

#

#

# class Person:

#     role = 'person'  # 角色屬性

#

#     def walk(self):  # 方法,動態屬性

#         print("person is walking...")

#

#

# # 屬性的引用

# # 查看人的role屬性

# print(Person.role)

# # 引用人的走路方法,注意,這裏不是在調用

# print(Person.walk)

 

# # 實例化: 類名加括號就是實例化

# class Person:

#     role = 'person'  # 角色屬性

#

#     def __init__(self, name):

#         self.name = name

#

#     def walk(self):  # 方法,動態屬性

#         print("person is walking...")

#

#

# # 實例化的過程就是類——>對象的過程 egg 爲對象

# # 語法:對象名 = 類名(參數)

# egg = Person('egon')

# # 查看對象的屬性和調用方法

# print(egg.name)

# egg.walk()

# print(egg.walk())

"""

class 類名:

    def __init__(self,參數1,參數2):

        self.對象的屬性1 = 參數1

        self.對象的屬性2 = 參數2

 

    def 方法名(self):pass

 

    def 方法名2(self):pass

 

對象名 = 類名(1,2)  #對象就是實例,代表一個具體的東西

                  #類名() : 類名+括號就是實例化一個類,相當於調用了__init__方法

                  #括號裏傳參數,參數不需要傳self,其他與init中的形參一一對應

                  #結果返回一個對象

對象名.對象的屬性1   #查看對象的屬性,直接用 對象名.屬性名 即可

對象名.方法名()     #調用類中的方法,直接用 對象名.方法名() 即可

 

"""

 

# # 創建一個狗類

# class Dog:

#     role = 'dog'

#

#     def __init__(self, name, breed, aggressivity, life_value):

#         self.name = name  # 每一隻狗都有自己的暱稱;

#         self.breed = breed  # 每一隻狗都有自己的品種;

#         self.aggressivity = aggressivity  # 每一隻狗都有自己的攻擊力;

#         self.life_value = life_value  # 每一隻狗都有自己的生命值;

#

#     def attack(self, animal):

#         # 狗被攻擊,狗的生命值會下降

#         animal.life_value -= self.aggressivity

#

#

# # 實例化二哈

# ha1 = Dog('大二哈', '哈士奇', 10, 1000)

# ha2 = Dog('小二哈', '哈士奇', 7, 800)

# # 交互

# print(ha1.life_value)

# print(ha2.life_value)

#

# ha1.attack(ha2)

# ha2.attack(ha1)

#

# print(ha1.life_value)

# print(ha2.life_value)

 

 

# # 計算圓的周長和麪積

# from math import pi

#

#

# class Circle:

#     """

#      定義了一個圓形類;

#     提供計算面積(area)和周長(perimeter)的方法

#

#     """

#     # 圓的半徑

#     def __init__(self, radius):

#         self.radius = radius

#

#     def area(self):

#         return pi * self.radius * self.radius

#

#     def perimeter(self):

#         return 2 * pi * self.radius

#

#

# # 實例化一個圓

# circle = Circle(10)

# # 計算對象圓的面積

# area1 = circle.area()

# # 計算對象圓的周長

# per1 = circle.perimeter()

# # 打印圓面積和周長

# print(area1, per1)

 

"""

創建一個類就會創建一個類的名稱空間

類的靜態屬性和動態屬性:

    靜態屬性就是直接在類中定義的變量

    動態屬性就是定義在類中的方法

類的數據屬性是共享給所有對象的,地址相同

類的動態屬性是綁定到所有對象的,地址不同

"""

 

# # 類的組合指的是,在一個類中以另外一個類的對象作爲數據屬性

# class Weapon:

#     # 這是該裝備的主動技能

#     def prick(self, obj):

#         obj.life_value -= 500

#

#

# class Person:

#     role = 'person'

#

#     def __init__(self, name):

#         self.name = name

#         # 給角色綁定一個武器;Weapon實例化爲Person的一個屬性

#         self.weapon = Weapon()

#

#

# egg = Person('egon')

# # 直接egg.weapon來使用組合類中的所有方法

# egg.weapon.prick()

 

# # 圓環的面積周長的組合類

# from math import pi

#

#

# class Circle:

#     """

#     定義了一個圓形類;

#     提供計算面積(area)和周長(perimeter)的方法

#     """

#     def __init__(self, radius):

#         self.radius = radius

#

#     def area(self):

#         return pi * self.radius * self.radius

#

#     def perimeter(self):

#         return 2 * pi * self.radius

#

#

# class Ring:

#     """

#     定義了一個圓環類

#     提供圓環的面積和周長的方法

#     """

#     def __init__(self, radius_outside, radius_inside):

#         self.outside_circle = Circle(radius_outside)

#         self.inside_circle = Circle(radius_inside)

#

#     def area(self):

#         return self.outside_circle.area() - self.inside_circle.area()

#

#     def perimeter(self):

#         return self.outside_circle.perimeter() + self.inside_circle.perimeter()

#

#

# ring = Ring(10, 5)

# # 計算環形的周長

# print(ring.perimeter())

# # 計算環形的面積

# print(ring.area())

 

 

# # 類與組合的類之間的關係,它是一種“有”關係

# # 當類之間有顯著不同,且較小的類是較大的類所需要的組件

# class BirthDate:

#     """

#     關於生日信息的類,年月日

#     """

#     def __init__(self, year, month, day):

#         self.year = year

#         self.month = month

#         self.day = day

#

#

# class Couse:

#     """

#     課程信息的類,名稱價格週期

#     """

#     def __init__(self, name, price, period):

#         self.name = name

#         self.price = price

#         self.period = period

#

#

# class Teacher:

#     """

#     教師信息的類,姓名性別生日授課

#     """

#     def __init__(self, name, gender, birth, course):

#         self.name = name

#         self.gender = gender

#         self.birth = birth

#         self.course = course

#

#     def teach(self):

#         print('teaching')

#

#

# t1 = Teacher('egon', 'male',

#              BirthDate('1995', '1', '27'),

#              Couse('python', '28000', '4 months')

#              )

#

# print(t1.birth.year, t1.birth.month, t1.birth.day)

# print(t1.course.name, t1.course.price, t1.course.period)

# print(t1.birth)

 

# # 人狗大戰

# class Person:

#     """

#     定義一個人的類, 姓名攻擊力生命值金錢

#     """

#     role = 'person'

#

#     def __init__(self, name, aggressivity, life_value, money):

#         self.name = name

#         self.aggressivity = aggressivity

#         self.life_value = life_value

#         self.money = money

#

#     def attack(self, dog):

#         """

#         定義了人的一個攻擊的方法

#         """

#         dog.life_value -= self.aggressivity

#

#

# class Dog:

#     """

#     定義一個狗的類,暱稱品種攻擊力生命值

#     """

#     role = 'dog'  # 狗的角色屬性都是狗

#

#     def __init__(self, name, breed, aggressivity, life_value):

#         self.name = name

#         self.breed = breed

#         self.aggressivity = aggressivity

#         self.life_value = life_value

#

#     def bite(self, people):

#         """

#         定義了一個攻擊方法

#         """

#         people.life_value -= self.aggressivity

#

#

# class Weapon:

#     """

#     定義了一個武器,名稱價格攻擊附加耐久值

#     """

#     def __init__(self, name, price, aggrev, life_value):

#         self.name = name

#         self.price = price

#         self.aggrev = aggrev

#         self.life_value = life_value

#

#     def update(self, obj):

#         """

#         定義使用武器附加的方法

#         """

#         obj.money -= self.price

#         obj.aggressivity += self.aggrev

#         obj.life_value += self.life_value

#

#     def prick(self, obj):

#         """

#         定義一個攻擊技能的方法

#         """

#         obj.life_value -= 500

#

#

# # 實例化武器、狗、人

# lance = Weapon('長矛', 200, 6, 100)

# egg = Person('egon', 10, 1000, 600)

# ha2 = Dog('大哈', '哈士奇', 10, 1000)

#

# # 購置裝備

# if egg.money > lance.price:

#     lance.update(egg)

#     egg.weapon = lance

#

# print(egg.money, egg.life_value, egg.aggressivity)

#

# print(ha2.life_value)

# # 這裏自帶了武器的攻擊附加傷害

# egg.attack(ha2)

# print(ha2.life_value)

# # 發動武器技能加成

# egg.weapon.prick(ha2)

# print(ha2.life_value)

 

# # 類的繼承

# # 定義父類1

# class ParentClass1:

#     pass

#

#

# # 定義父類2

# class ParentClass2:

#     pass

#

#

# # 單繼承

# # 基類是ParentClass1,派生類是SubClass

# class SubClass1(ParentClass1):

#     pass

#

#

# # python支持多繼承,用逗號分隔開多個繼承的類

# class SubClass2(ParentClass1, ParentClass2):

#     pass

#

#

# print(SubClass1.__bases__)

# print(SubClass2.__bases__)

# # 無指定基類,默認繼承object類,其是所有python類的基類

# print(ParentClass1.__bases__)

 

# # 抽象:即抽取類似或者說比較像的部分。

# # 繼承是基於抽象的結果,通過繼承的方式表達出抽象的結構

# # 將奧巴馬和梅西這倆對象比較像的部分抽取成類;

# # 將人,豬,狗這三個類比較像的部分抽取成父類。

# # 抽象是分析過程,繼承是實現方式

# class Animal:

#

#     def eat(self):

#         print("%s 喫 " % self.name)

#

#     def drink(self):

#         print("%s 喝 " % self.name)

#

#

# class Cat(Animal):

#

#     def __init__(self, name):

#         self.name = name

#         self.breed = '貓'

#

#     def climb(self):

#         print('爬樹')

#

#

# class Dog(Animal):

#

#     def __init__(self, name):

#         self.name = name

#         self.breed = '狗'

#

#     def look_after_house(self):

#         print("%s " '汪汪叫' % self.name)

#

#

# c1 = Cat('小白貓')

# c1.eat()

#

# d1 = Dog('大金毛')

# d1.drink()

#

# d2 = Dog('帥邊牧')

# d2.look_after_house()

 

# # 派生,子類可添加新的屬性或重新定義這些屬性

# # 重新定義的屬性不會影響到父類

# class A:

#     def hahaha(self):

#         print('A')

#

#

# class B(A):

#     def hahaha(self):

#         super().hahaha()

#         print('B')

#

#

# class C(A):

#     def hahaha(self):

#         print('C')

#

#

# class D(A):

#     def hahaha(self):

#         print('D')

#

#     def newmethod(self):

#         print("派生,新屬性")

#

#

# a = A()

# b = B()

# c = C()

# d = D()

# a.hahaha()

# print("---***---")

# b.hahaha()

# print("---***---")

# c.hahaha()

# print("---***---")

# super(B, b).hahaha()

# print("---***---")

# d.hahaha()

# d.newmethod()

 

# 接口類,借用abc模塊來實現接口

# 接口繼承實質上是要求“做出一個良好的抽象,

# 這個抽象規定了一個兼容接口,

# 使得外部調用者無需關心具體細節,

# 可一視同仁的處理實現了特定接口的所有對象”

# ——這在程序設計上,叫做歸一化。

# 歸一化,讓使用者無需關心對象的類是什麼,

# 只需要的知道這些對象都具備某些功能

 

# # 抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被實例化

# # 子類必須實現抽象方法

# # 需要藉助模塊abc來實現

# import abc

#

#

# class All_file(metaclass=abc.ABCMeta):

#     all_type = 'file'

#

#     @abc.abstractmethod  # 定義抽象方法,無需實現功能

#     def read(self):

#         # 子類必須定義讀功能

#         pass

#

#     @abc.abstractmethod

#     def write(self):

#         # 子類必須定義些功能

#         pass

#

#

# # 子類繼承抽象類,但是必須定義read和write方法

# class Txt(All_file):

#     def read(self):

#         print('文本數據的讀取方法')

#

#     def write(self):

#         print('文本數據的寫入方法')

#

#

# # 子類繼承抽象類,但是必須定義read和write方法

# class Process(All_file):

#     def read(self):

#         print('進程數據的讀取方法')

#

#     def write(self):

#         print('進程數據的寫入方法')

#

#

# wenbenwenjian = Txt()

# jinchengwenjian = Process()

#

# # 這樣都是被歸一化了,也就是一切皆文件的思想

# wenbenwenjian.read()

# jinchengwenjian.write()

#

# print(wenbenwenjian.all_type)

# print(jinchengwenjian.all_type)

 

# 抽象類的本質還是類,指的是一組類的相似性包括數據屬性和函數屬性

# 接口強調函數屬性的相似性

 

# 抽象類是一個介於類和接口直接的一個概念,

# 同時具備類和接口的部分特性,可以用來實現歸一化設計

# 繼承抽象類的過程中,我們應該儘量避免多繼承;

# 繼承接口的時候,我們反而鼓勵你來多繼承接口

# 接口隔離原則:使用多個專門的接口,而不使用單一的總接口。

# 即客戶端不應該依賴那些不需要的接口。

"""

繼承順序  深度優先和廣度優先

經典類:C1 和 C2 都是經典類

class C1:

    pass

 

class C2:

    pass

 

新式類: N1 和 N2都是新式類

class N1(object):

    pass

   

class N2(N1):

    pass

 

類是經典類時,多繼承的情況下,會按照深度優先方式查找

類是新式類時,多繼承情況下,會按照廣度優先的方式查找

python3中統一都是新式類

python2中才分新式類與經典類

"""

 

# class A(object):

#     def test(self):

#         print('from A')

#

#

# class B(A):

#     def test(self):

#         print('from B')

#

#

# class C(A):

#     def test(self):

#         print('from C')

#

#

# class D(B):

#     def test(self):

#         print('from D')

#

#

# class E(C):

#     def test(self):

#         print('from E')

#

#

# class F(D, E):

#     # def test(self):

#     #     print('from F')

#     pass

#

#

# f1 = F()

# f1.test()

# # 只有新式纔有這個屬性可以查看線性列表,經典類沒有這個屬性

# print(F.__mro__)

 

"""

繼承的作用:

# 減少代碼的重用

# 提高代碼可讀性

# 規範編程模式

抽象:抽象即抽取類似或者說比較像的部分。是一個從具題到抽象的過程。

繼承:子類繼承了父類的方法和屬性

派生:子類在父類方法和屬性的基礎上產生了新的方法和屬性

1.多繼承問題

在繼承抽象類的過程中,我們應該儘量避免多繼承;

而在繼承接口的時候,我們反而鼓勵你來多繼承接口

2.方法的實現

在抽象類中,我們可以對一些抽象方法做出基礎實現;

而在接口類中,任何方法都只是一種規範,具體的功能需要子類實現

"""

 

"""

多態指的是一類事物有多種形態

多態性(多態動態綁定)

多態性是指在不考慮實例類型的情況下使用實例

"""

# # 動物有多種形態:狗,貓,豬

# import abc

#

#

# # 同一類事物:動物

# class Animal(metaclass=abc.ABCMeta):

#     @abc.abstractmethod

#     def talk(self):

#         pass

#

#

# # 動物的形態之一:人

# class Cat(Animal):

#     def talk(self):

#         print('喵喵')

#

#

# # 動物的形態之二:狗

# class Dog(Animal):

#     def talk(self):

#         print('汪汪')

#

#

# # 動物的形態之三:豬

# class Pig(Animal):

#     def talk(self):

#         print('豬昂昂')

#

#

# c1 = Cat()

# d1 = Dog()

# p1 = Pig()

#

# # c1、d1、p1都是動物,只要是動物肯定有talk方法

# # 於是我們可以不用考慮它們三者的具體是什麼類型,而直接使用

# c1.talk()

# d1.talk()

# p1.talk()

#

#

# # 更進一步,我們可以定義一個統一的接口來使用

# def func(obj):

#     obj.talk()

#

#

# func(c1)

 

"""

封裝:隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。

優點:

    1. 將變化隔離;

    2. 便於使用;

    3. 提高複用性;

    4. 提高安全性;

封裝的原則:

     1. 將不需要對外提供的內容都隱藏起來;

     2. 把屬性都隱藏,提供公共方法對其訪問。

私有變量和私有方法:

在python中用雙下劃線開頭的方式將屬性隱藏起來(設置成私有的)

 

封裝在於明確區分內外,使得類實現者可以修改封裝內的東西而不影響外部調用者的代碼;

"""

 

 

# 其實這僅僅這是一種變形操作

# 類中所有雙下劃線開頭的名稱如__x都會自動變形成:_類名__x的形式:

 

 

class A:

    # 類的數據屬性就應該是共享的,

    # 但是語法上是可以把類的數據屬性設置成私有的如__N,會變形爲_A__N

    __N = 0

 

    def __init__(self):

        # 變形爲self._A__X

        self.__X = 10

        # 變形爲_A__foo

 

    def __foo(self):

        print('from A')

 

    def bar(self):

        # 只有在類內部纔可以通過__foo的形式訪問到.

        self.__foo()

 

 

# A._A__N是可以訪問到的,

# 即這種操作並不是嚴格意義上的限制外部訪問,

# 僅僅只是一種語法意義上的變形

"""

變形的特點:

 

1.類中定義的__x只能在內部使用,如self.__x,引用的就是變形的結果。

 

2.這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。

 

3.在子類定義的__x不會覆蓋在父類定義的__x,因爲子類中變形成了:

   _子類名__x,而父類中變形成了:_父類名__x,

   即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。

 

注意問題:

1.這種機制也並沒有真正意義上限制我們從外部直接訪問屬性,

  知道了類名和屬性名就可以拼出名字:_類名__屬性,然後就可以訪問了,如a._A__N

2.變形的過程只在類的內部生效,在定義後的賦值操作,不會變形

3.在繼承中,父類如果不想讓子類覆蓋自己的方法,可以將方法定義爲私有的

 

"""

"""

property是一種特殊的屬性,訪問它時會執行一段功能(函數)然後返回值

將一個類的函數定義成property特性以後,使用obj.name的時候,

無法察覺name是執行了一個函數然後計算出來的,這種特性的使用方式遵循了統一訪問的原則

 

一個靜態屬性property本質就是實現了get,set,delete三種方法

 

面向對象的封裝有三種方式:

【public】

這種其實就是不封裝,是對外公開的

【protected】

這種封裝方式對外不公開,但對朋友(friend)或者子類(形象的說法是“兒子”,

但我不知道爲什麼大家 不說“女兒”,

就像“parent”本來是“父母”的意思,但中文都是叫“父類”)公開

【private】

這種封裝對誰都不公開

 

"""

# # 計算圓的周長和麪積

# from math import pi

#

#

# class Circle:

#     """

#      定義了一個圓形類;

#     提供計算面積(area)和周長(perimeter)的方法

#

#     """

#     # 圓的半徑

#     def __init__(self, radius):

#         self.radius = radius

#

#     @property

#     def area(self):

#         return pi * self.radius * self.radius

#

#     @property

#     def perimeter(self):

#         return 2 * pi * self.radius

#

#

# # 實例化一個圓

# c = Circle(10)

# # 計算對象圓的面積和周長並打印

# print(c.area, c.perimeter)

# # 此時的特性area和perimeter不能被賦值

 

 

# class Foo:

#     def __init__(self, val):

#         # 將所有的數據屬性都隱藏起來

#         self.__NAME = val

#

#     @property

#     def name(self):

#         # obj.name訪問的是self.__NAME(這也是真實值的存放位置)

#         return self.__NAME

#

#     @name.setter

#     def name(self, value):

#         # 在設定值之前進行類型檢查

#         if not isinstance(value, str):

#             raise TypeError('%s must be str' % value)

#         # 通過類型檢查後,將值value存放到真實的位置self.__NAME

#         self.__NAME = value

#

#     @name.deleter

#     def name(self):

#         raise TypeError('Can not delete')

#

#

# f = Foo('egon')

# print(f.name)

# # 拋出異常'TypeError: 10 must be str'

# f.name = 10

# # 拋出異常'TypeError: Can not delete'

# del f.name

 

# # 一個靜態屬性property本質就是實現了get,set,delete三種方法

# class Foo:

#

#     @property

#     def AAA(self):

#         print('get的時候運行我啊')

#

#     @AAA.setter

#     def AAA(self,value):

#         print('set的時候運行我啊')

#

#     @AAA.deleter

#     def AAA(self):

#         print('delete的時候運行我啊')

#

#

# # 只有在屬性AAA定義property後才能定義AAA.setter,AAA.deleter

# f1 = Foo()

# f1.AAA

# f1.AAA = 'aaa'

# del f1.AAA

 

# class Foo:

#     def get_AAA(self):

#         print('get的時候運行我啊')

#

#     def set_AAA(self,value):

#         print('set的時候運行我啊')

#

#     def delete_AAA(self):

#         print('delete的時候運行我啊')

#         # 內置property三個參數與get,set,delete一一對應

#     AAA = property(get_AAA, set_AAA, delete_AAA)

#

#

# f1 = Foo()

# f1.AAA

# f1.AAA = 'aaa'

# del f1.AAA

 

# 使用方式

# class Goods:

#

#     def __init__(self):

#         # 原價

#         self.original_price = 100

#         # 折扣

#         self.discount = 0.8

#

#     @property

#     def price(self):

#         # 實際價格 = 原價 * 折扣

#         new_price = self.original_price * self.discount

#         return new_price

#

#     @price.setter

#     def price(self, value):

#         self.original_price = value

#

#     @price.deleter

#     def price(self):

#         del self.original_price

#

#

# obj = Goods()

# # 獲取商品價格

# # obj.price

# # 修改商品原價

# obj.price = 200

# print(obj.price)

# # 刪除商品原價

# del obj.price

# obj.price = 300

# print(obj.price)

"""

封裝器的作用或區別

Classmethod:

Staticmethod

"""

 

 

class Classmethod_Demo():

    role = 'dog'

 

    @classmethod

    def func(cls):

        print(cls.role)

 

Classmethod_Demo.func()

 

 

class Staticmethod_Demo():

    role = 'dog'

 

    @staticmethod

    def func():

        print("當普通方法用")

 

Staticmethod_Demo.func()

 

 

class A:

    __role = 'CHINA'

 

    @classmethod

    def show_role(cls):

        print(cls.__role)

 

    @staticmethod

    def get_role():

        return A.__role

 

    @property

    def role(self):

        return self.__role

 

 

a = A()

print(a.role)

print(a.get_role())

a.show_role()

願有更多的朋友,在網頁筆記結構上分享更邏輯和易讀的形式:

鏈接:暫無
提取碼:暫無

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章