天天看點

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

重點解釋,此對象非彼對象,耐心看完你會對面向對象有一個深刻細緻的了解

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

這是個人對面向對象的一些小了解,Python是一條慢慢長路,孤軍奮進會很累,如果累的話可以在文末可以看到辣條我的明片,我們一起奮筆疾書,高歌猛進,當然了要是來求學的我也是不介意的并且我之前還有一些能用的上的源碼,教程啥的,廢話不多說,不耽誤大家的寶貴時間了~

目錄

  • 一.面向過程程式設計
    • 優點
    • 缺點
  • 二.面向對象程式設計
    • 2.1 類
    • 2.2屬性查找
    • 2.3綁定方法
    • 2.4類即類型
    • 2.5新式類
    • 2.6經典類
    • 2.7繼承與派生
      • 2.7.1檢視繼承關系
    • 2.8組合
      • 2.8.1在子派生的新方法中重用父類功能的兩種方式
    • 2.9菱形繼承
        • 2.9.1保留最後的G最後一次繼承
      • 2.9.2重用父類功能
    • 2.10多态
    • 2.11封裝
      • 2.11.1強制調用
    • 2.12特性property
      • 2.12.1檢視隐藏封裝屬性
    • 2.13綁定方法和非綁定方法
    • 2.14判斷類
    • 2.15反射
      • 2.15.1什麼是反射
      • 2.15.2 如何用
  • 類中的魔法方法
    • 3.1str方法
    • 3.2 del析構方法

一.面向過程程式設計

1.核心過程二字,過程指的是解決問題的步驟,即先幹什麼、再幹什麼、然後幹什麼…

2.基于該思想編寫程式就好比在設計一條流水線,是一種機械式的思維方式

優點

複雜的問題流程化、進而簡單化
           

缺點

擴充性極差
           

二.面向對象程式設計

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

2.1 類

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

2.2屬性查找

def __init__(self, x, y, z): #會在調用類時自動觸發
           

2.3綁定方法

在類内部定義的函數(沒有被任何裝飾器修飾的),預設就是綁定給對象用的:精髓在于會自動将對象傳入,當成第一個參數 self

class OldboyStudent:
    school='oldboy'

def __init__(self, x, y, z): #會在調用類時自動觸發
    self.name = x #stu1.name='耗哥'
    self.age = y  #stu1.age=18
    self.sex = z #stu1.sex='male'

def choose_course(self,x):
    print('%s is choosing course' %self.name)

def func(self):
    pass
# 類名稱空間中定義的資料屬性和函數屬性都是共享給所有對象用的
# 對象名稱空間中定義的隻有資料屬性,而且時對象所獨有的資料屬性

stu1=OldboyStudent('耗哥',18,'male')
stu2=OldboyStudent('豬哥',17,'male')
stu3=OldboyStudent('帥翔',19,'female')
           

在類内部定義的函數如果被裝飾器@classmethod裝飾,那麼則是綁定給類的,應該由類來調用,類來調用就自動将類當作第一個參數自動傳入

非綁定:[br/>類中定義的函數如果被裝飾器@staticmethod裝飾,那麼該函數就變成非綁定方法

既不與類綁定,又不與對象綁定,意味着類與對象都可以來調用

但是無論誰來調用,都沒有任何自動傳值的效果,就是一個普通函數]

2.4類即類型

#在python3中統一了類與類型的概念,類就是類型
class OldboyStudent:
    school='oldboy'

    def __init__(self, x, y, z): #會在調用類時自動觸發
        self.name = x #stu1.name='耗哥'
        self.age = y  #stu1.age=18
        self.sex = z #stu1.sex='male'

    def choose_course(self,x):
        print('%s is choosing course' %self.name)

stu1=OldboyStudent('耗哥',18,'male')
# stu1.choose_course(1) #OldboyStudent.choose_course(stu1,1)
# OldboyStudent.choose_course(stu1,1)


l=[1,2,3] #l=list([1,2,3])
# print(type(l))
# l.append(4) #list.append(l,4)
list.append(l,4)
print(l)
           

2.5新式類

​ 但凡繼承了object的類以及該類的子類,都是新式類

2.6經典類

​ 沒有繼承object的類以及該類的子類,都是經典類

在python3中都是新式類,隻有在python2中才差別新式類與經典類
           

2.7繼承與派生

2.7.1檢視繼承關系

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了
#派生:子類中新定義的屬性,子類在使用時始終以自己的為準
class OldboyPeople:
    school = 'oldboy'
    def __init__(self,name,age,sex):
        self.name = name #tea1.name='egon'
        self.age = age #tea1.age=18
        self.sex = sex #tea1.sex='male'



class OldboyStudent(OldboyPeople):
    def choose_course(self):
        print('%s is choosing course' %self.name)


class OldboyTeacher(OldboyPeople):
    #            tea1,'egon',18,'male',10
    def __init__(self,name,age,sex,level):
        # self.name=name
        # self.age=age
        # self.sex=sex
        OldboyPeople.__init__(self,name,age,sex)
        self.level=level

    def score(self,stu_obj,num):
        print('%s is scoring' %self.name)
        stu_obj.scoe=99

stu1=OldboyStudent('耗哥',18,'male')
tea1=OldboyTeacher('egon',18,'male',10)

#對象查找屬性的順序:對象自己-》對象的類-》父類-》父類。。。
# print(stu1.school)
# print(tea1.school)
# print(stu1.__dict__)
# print(tea1.__dict__)

tea1.score(stu1,99)
print(tea1.__dict__)
print(stu1.__dict__)


# 在子類派生出的新功能中重用父類功能的方式有兩種:
#1、指名道姓通路某一個類的函數:該方式與繼承無關
           

2.8組合

比如老師需要給學生打分需要把學生對象添加到老師方法裡面,該方法修改學生的分數屬性

比如課程對象添加到老師對象和學生對象的屬性裡面,老師對象和學生對象就有了改課程對象的方法

2.8.1在子派生的新方法中重用父類功能的兩種方式

Vehicle.__init__(self,name,speed,load,power)
           
#super(Subway,self) 就相當于執行個體本身 在python3中super()等同于super(Subway,self)
           

2.9菱形繼承

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了
print(A.mro())
           

找到A類裡的繼承順序

[, , , , , , , ]

2.9.1保留最後的G最後一次繼承

class G(object):
    # def test(self):
    #     print('from G')
    pass

class E(G):
    # def test(self):
    #     print('from E')
    pass

class B(E):
    # def test(self):
    #     print('from B')
    pass

class F(G):
    # def test(self):
    #     print('from F')
    pass

class C(F):
    # def test(self):
    #     print('from C')
    pass

class D(G):
    # def test(self):
    #     print('from D')
    pass

class A(B,C,D):
    def test(self):
        print('from A')
    # pass

obj=A()
print(A.mro())
# obj.test() #A->B->E-C-F-D->G-object
           
# 在子派生的新方法中重用父類功能的兩種方式
# 方式一:與繼承無關
# 指名道姓法,直接用:類名.函數名
class OldboyPeople:
    school = 'oldboy'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,stu_id):
        OldboyPeople.__init__(self,name,age,sex)
        self.stu_id=stu_id

    def choose_course(self):
        print('%s is choosing course' %self.name)


# 方式二:嚴格以來繼承屬性查找關系
# super()會得到一個特殊的對象,該對象就是專門用來通路父類中的屬性的(按照繼承的關系)
# super().__init__(不用為self傳值)
# 注意:
# super的完整用法是super(自己的類名,self),在python2中需要寫完整,而python3中可以簡寫為super()
class OldboyPeople:
    school = 'oldboy'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,stu_id):
        # OldboyPeople.__init__(self,name,age,sex)
        super(OldboyStudent,self).__init__(name,age,sex)
        self.stu_id=stu_id

    def choose_course(self):
        print('%s is choosing course' %self.name)


stu1=OldboyStudent('豬哥',19,'male',1)
print(stu1.__dict__)

print(OldboyStudent.mro())


# class A:
#     def f1(self):
#         print('A.f1')
#
# class B:
#     def f2(self):
#         super().f1()
#         print('B.f2')
#
# class C(B,A):
#     pass
#
# obj=C()
# print(C.mro()) #C-》B->A->object
# obj.f2()
           

2.9.2重用父類功能

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

2.10多态

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了
1、類的屬性和對象的屬性有什麼差別?'''
#類屬性是共有的,任何執行個體化的對象都能夠拿到類屬性,而對象屬性是對象自己本身的特性。

'''2、面向過程程式設計與面向對象程式設計的差別與應用場景?'''
#面向過程是機械化的思維方式,解決問題的步驟是先幹什麼,後幹什麼, 把簡單的問題流程化進而簡單化。代碼的擴充性不好
#一般運用在程式不需要經常改變的地方
#面向過程是一種上帝式的思維,解決問題是找一個個的對象,由對象之間互相互動,代碼的擴充性好。經常用在需要改動的地方

'''3、類和對象在記憶體中是如何儲存的。'''
#類在定義階段就會産生一個名稱空間,然後将産生的名字放到記憶體空間中,對象是在執行個體化過程中産生的名稱空間,該名稱空間存放對象私有的屬性,以及綁定方法。

'''    4、什麼是綁定到對象的方法,、如何定義,如何調用,給誰用?有什麼特性'''
#類中定義的方法就是給執行個體化的對象綁定的方法,在類的定義階段就定義一個函數,函數必須要加上一個參數,用來接收對象本身
#執行個體化的對象可以直接調用綁定方法,誰來調用就給誰綁定一個方法。
           

2.11封裝

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

2.11.1強制調用

print(People._People__country)
           

2.12特性property

#property裝飾器用于将被裝飾的方法僞裝成一個資料屬性,在使用時可以不用加括号而直接引用
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)
#
peo1=People('egon',75,1.8)

peo1.height=1.85
print(peo1.bmi)
           

2.12.1檢視隐藏封裝屬性

#
class People:
    def __init__(self,name):
        self.__name=name

    @property # 檢視obj.name
    def na(self):
        return '<名字是:%s>' %self.__name

    @na.setter #修改obj.name=值
    def na(self,name):
        if type(name) is not str:
            raise TypeError('名字必須是str類型傻叉')
        self.__name=name

    @na.deleter #删除del obj.name
    def na(self):
        # raise PermissionError('不讓删')
        print('不讓删除傻叉')
        # del self.__name

peo1=People('egon')
# print(peo1.name)
#
# print(peo1.name)

# peo1.name='EGON'
# print(peo1.name)

# del peo1.na


print(peo1.na)

#
#
#
# class People:
#     def __init__(self,name):
#         self.__name=name
#
#
#     def tell_name(self):
#         return '<名字是:%s>' %self.__name
#
#     def set_name(self,name):
#         if type(name) is not str:
#             raise TypeError('名字必須是str類型傻叉')
#         self.__name=name
#
#     def del_name(self):
#         print('不讓删除傻叉')
#
#     name=property(tell_name,set_name,del_name)
#
#
# peo1=People('egon')
#
# print(peo1.name)
# peo1.name='EGON'
# print(peo1.name)
# del peo1.name
class People:
    def __init__(self,name):
        self.__name=name

    @property # 檢視obj.name
    def na(self):
        return '<名字是:%s>' %self.__name

    @na.setter #修改obj.name=值
    def na(self,name):
        if type(name) is not str:
            raise TypeError('名字必須是str類型傻叉')
        self.__name=name

    @na.deleter #删除del obj.name
    def na(self):
        # raise PermissionError('不讓删')
        print('不讓删除傻叉')
        # del self.__name

peo1=People('egon')
# print(peo1.name)
#
# print(peo1.name)

# peo1.name='EGON'
# print(peo1.name)

# del peo1.na
           

2.13綁定方法和非綁定方法

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了

2.14判斷類

你知道的Python面向對象真的是全面的嘛?看看這個你就知道了
import settings
import uuid

class Mysql:
    def __init__(self,ip,port):
        self.uid=self.create_uid()
        self.ip=ip
        self.port=port

    def tell_info(self):
        print('%s:%s' %(self.ip,self.port))

    @classmethod
    def from_conf(cls):
        return cls(settings.IP, settings.PORT)

    @staticmethod
    def func(x,y):
        print('不與任何人綁定')

    @staticmethod
    def create_uid():
        return uuid.uuid1()

# 預設的執行個體化方式:類名(..)
obj=Mysql('10.10.0.9',3307)

# 一種新的執行個體化方式:從配置檔案中讀取配置完成執行個體化
# obj1=Mysql.from_conf()
# obj1.tell_info()

# obj.func(1,2)
# Mysql.func(3,4)
# print(obj.func)
# print(Mysql.func)

print(obj.uid)
           

2.15反射

2.15.1什麼是反射

​ 通過字元串來操作類或者對象的屬性

2.15.2 如何用

class People:
    country='China'
    def __init__(self,name):
        self.name=name

    def eat(self):
        print('%s is eating' %self.name)

peo1=People('egon')


print(hasattr(peo1,'eat')) #peo1.eat

print(getattr(peo1,'eat')) #peo1.eat
print(getattr(peo1,'xxxxx',None))

# setattr(peo1,'age',18) #peo1.age=18
# print(peo1.age)

# print(peo1.__dict__)
# delattr(peo1,'name') #del peo1.name
# print(peo1.__dict__)
# 還行


class Ftp:
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port

    def get(self):
        print('GET function')

    def put(self):
        print('PUT function')

    def run(self):
        while True:
            choice=input('>>>: ').strip()
            print(choice,type(choice))
            if hasattr(self,choice):
                method=getattr(self,choice)
                method()
            else:
                print('輸入的指令不存在')

            # method=getattr(self,choice,None)
            # if method is None:
            #     print('輸入的指令不存在')
            # else:
            #     method()

conn=Ftp('1.1.1.1',23)
conn.run()
           

類中的魔法方法

3.1str方法

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

    #在對象被列印時,自動觸發,應該在該方法内采集與對象self有關的資訊,然後拼成字元串傳回
    def __str__(self):

# print('======>')

        return '<name:%s age:%s>' %(self.name,self.age)
obj=People('egon',18)
obj1=People('alex',18)
print(obj)  #obj.__str__()
print(obj)  #obj.__str__()
print(obj)  #obj.__str__()
print(obj1)  #obj1.__str__()

d={'x':1} #d=dict({'x':1})
print(d)
           

3.2 del析構方法

__del__會在對象被删除之前自動觸發
class People:
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.f=open('a.txt','rt',encoding='utf-8')

    def __del__(self):

# print('run=-====>')

# 做回收系統資源相關的事情

        self.f.close()

obj=People('egon',18)

print('主')