1. 程式人生 > >day31 Pyhton 面向物件的基礎 三大特性

day31 Pyhton 面向物件的基礎 三大特性

一.內容回顧

封裝

  1.概念 筆記

  2.__名字 在類的外部就不能用了

  3.私有化的 不能被子類繼承,也不能在其他任何類中呼叫

三個裝飾器方法(裝飾類中的方法)

  1.不被修飾的  普通方法,會使用物件self的屬性

  [email protected]  類方法,不使用self的屬性,用類cls的屬性

  [email protected] 靜態方法,不用self的屬性和類cls的屬性

  [email protected]  將一個方法偽裝成一個屬性

    def  函式名

    @函式名.setter

    @函式名.deleter

# from math import pi
# class Circle:
#     def __init__(self,r):
#         self.r = r
#     @property
#     def area(self):
#         return pi*self.r**2
#     @property
#     def perimeter(self):     # 周長
#         return 2*pi*self.r
#     @perimeter.setter
#     def perimeter(self,新的周長):
# self.r = 新的周長 / 2 / pi

setter修改屬性值

# setter裝飾的函式名叫什麼 perimeter

# 那麼在這個函式中絕對不可以對這個函式名同名的屬性進行修改
# 程式的邏輯問題
    # 1. 不可以對某些計算結果直接賦值
    # 2. 一般是通過對計算結果產生影響的屬性進行重新賦值
    # 比如說對於圓這個例子 : 不能直接修改面積或者周長,應該通過修改半徑來帶動對應周長和麵積的改變
# 反射(不得不用)
# 使用字串的方式,操作物件的屬性(物件屬性,類的動態屬性(方法))
# 在python中 一切皆物件(類也是物件,物件也是物件,模組也是物件)
# a.b # a就是一個物件 # b本質上是一個變數名,也可以說是a的一個屬性 # 如果b是b 那麼就用a.b # 如果b是'b' 那麼就用getattr(a,'b')

二.面向物件的基礎
三大特性

  基礎的繼承

  基礎的封裝 __私有

兩個內建函式:issubclass  isinstance

反射: setattr/delattr  瞭解

內建方法: 你沒有應用場景

__new__

__call__

__str__/__repr__

__len__

__***item__系列

__hash__

__eq__

issubclass(子類,父類),如果真的有繼承關係,就返回True

class A(object):pass
class B(A):pass
print(issubclass(B,A))
# isinstance(物件,類)
# class A(object):pass
# a = A()
# print(isinstance(a,A))
# # 繼承
# class A(object):pass
# class B(A):pass
# b = B()
# print(isinstance(b,A)) # 檢測的物件是不是某個類以及其父類的物件
# print(type(b) is B)  # 檢測的是物件是不是某一個類的例項
# print(type(b) is A)
所有的反射 都是用字串 操作物件的屬性
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age

a = A('alex',83)
# hasattr
# print(getattr(a,'name'))#alex
# a.sex = '不詳'
# setattr(a,'sex','不詳')
# print(a.sex)#不詳
del a.age
# delattr(a,'age')
print(a.__dict__)#{'name': 'alex', 'sex': '不詳'}
 
 
 
# 關於內建方法的名字
    # 內建方法 雙下方法 魔術方法
# 內建方法的特點
    # 一定有某一個語法或者一種寫法自動觸發這個方法
 
 
 
# 重點掌握的
    # 哪些寫法 觸發 對應的內建方法
    # 例項化        __new__\__init__   構造方法(單例模式)\初始化方法
    # 物件()        __call__
    # del 物件      __del__            析構方法\物件刪除之前的收尾工作
    # print(物件)   __str__            讓一個物件的顯示更加清晰
    # str(物件)
    # '%s'%物件
    # repr()        __repr__           是__str__的備胎,並且還和repr(),%r格式化有關係
    # '%r'%物件
    # len(物件)     __len__
    # 物件[引數]    item系列
    # ==           __eq__
__call__ 物件用call方法可以呼叫函式__call__裡的方法
# __call__
class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def call(self):pass
    def __call__(self, *args, **kwargs):
        print('呼叫我啦')
alex = Student('alex',83)
# callable #檢視某個變數能否被呼叫
# callable(變數)  #返回True,那麼 變數() --> 呼叫
print(callable(Student))#True
print(callable(alex))#True
# alex()
alex.call()#呼叫我啦
 
 
 
class Dog(object):
    def __new__(cls, *args, **kwargs):
        pass
        dog_obj = object.__new__(cls)#呼叫父類object的__new__內建方法
        dog_obj = super().__new__(cls)##呼叫父類object的__new__內建方法,第二種方法
        return dog_obj
    def __init__(self,name,age):
        self.name = name
        self.age = age

wc = Dog('旺財',2)
print(wc.name)
 
 
 
# 一個類 只能例項化一次的方法
class Teacher:
    flag = None
    def __new__(cls, *args, **kwargs):
        if cls.flag is None:
            cls.flag = object.__new__(cls)    # 這一句話只能走一次
        return cls.flag
    def __init__(self,name):
        self.name = name

alex1 = Teacher('alex')
alex2 = Teacher('alex')
yuan = Teacher('yuan')
print(alex2.name)#yuan
print(yuan.name)#yuan
__del__
# 析構方法(瞭解) 刪除
class Teacher:
    def __init__(self,name):
        self.name = name
    def __del__(self):
        print('執行我啦')

alex = Teacher('ALEX')
del alex
print('hahaha')
 
 
 
# del alex    # 執行del 物件的時候 觸發__del__,在真正的刪除alex物件之前,執行的方法__del__
# 如果我們自己不刪除alex,那麼在程式的執行過程中或者最後,垃圾回收機制會替你執行del alex
# 1.del alex
# 2.執行__del__
# 3.刪除alex
 
 
 
class File(object):
    def __init__(self,file_name):
        self.f = open('file_name')
    def read(self):
        self.f.read(1024)
    def  __del__(self):# 物件使用的一些作業系統的資源的歸還工作/收尾工作
        self.f.close()
__str__
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __str__(self):  # 必須有返回值,必須返回一個str型別
        return '%s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
course_lst = []
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(str(python))
print('課程展示 : %s'%python)
 
 
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __str__(self):  # 必須有返回值,必須返回一個str型別
        return '%s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
course_lst = []
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(str(python))
print('課程展示 : %s'%python)
 
 
 
# list.__str__()
l = [1,2,3,4] # 物件 列表的物件
print(l)
print('[%s,%s,%s]'%(l[0],l[1],l[2]))
__repr__ 是str方法的備胎(有str呼叫str,沒有str走repr)
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __repr__(self):  # 必須有返回值,必須返回一個str型別
        return 'repr --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
    def __str__(self):  # 必須有返回值,必須返回一個str型別
        return 'str --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)

python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(linux)
 
 
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __repr__(self):  # 必須有返回值,必須返回一個str型別
        return 'repr --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
    def __str__(self):  # 必須有返回值,必須返回一個str型別
        return 'str --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print('%r'%python)#repr --> : python,19800,6 months,baoyuan
print('%s'%python)#str --> : python,19800,6 months,baoyuan
print(str(python))#str --> : python,19800,6 months,baoyuan
print(repr(python))#repr --> : python,19800,6 months,baoyuan
 
 
 
# 流暢的python : repr和str 如果只能寫一個的 寫repr
 
 
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __len__(self):
        return len(self.__dict__)
    def __getitem__(self,item):
        return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __delitem__(self, key):
        self.__dict__.pop(key)
python = Course('python',19800,'6 months','baoyuan')
print(len(python))
print(python.name)
print(python['name'])  # ==> 呼叫getitem
print(python['price'])  # ==> 呼叫getitem
python['name'] = 'python2.0'
print(python.name)
# del python.name#與下一句功能一樣
del python['name']
print(python.__dict__)#{'price': 19800, 'period': '6 months', 'teacher': 'baoyuan'}
# 有一些內建的函式/模組 要想能正確的使用它們 那麼必須按照它規定的語法來實現
__len__ 測量物件長度
class Ruler:
    def __init__(self,price,length,jingdu):
        self.length = length
        self.price = price
        self.jingdu = jingdu
    def __len__(self):
        return self.length
stu_ruler = Ruler(2.5,15,0.1)
print(len(stu_ruler))#15
__eq__ s1==s2 等於 s1.__eq__(s2)
class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        if self.name == other.name and self.age == other.age:
            return True
        return False

s1 = Student('賈衛東',20)
s2 = Student('賈衛東',20)
print(s1 == s2)   # s1.__eq__(s2)#True
print(s1 is s2)   # s1.__eq__(s2)#False
#夠通過這個字串 --> 程式中的變數名(類名\函式名\變數名\方法名\物件名)
class Manager:pass
class Student:pass
class Teacher:pass
identify = 'Student'
print(eval(identify)())#<__main__.Student object at 0x00000000025657B8>

反射 hasattr getattr

class Person:
    role = '人類'
    Country = '中國'

attr = input('>>>')  # role 人類
#                    # Country 中國
print(getattr(Person,'role'))
print(getattr(Person,'Country'))
if hasattr(Person,attr):
    print(getattr(Person,attr))

if attr == 'role':
    print(Person.role)
elif attr == 'Country':
    print(Person.Country)
class Person:
    role = '人類'
    @staticmethod
    def show_courses():
        print('所有課程')
# 反射類中的方法
# class Person:
#     role = '人類'
#     @staticmethod
#     def show_courses():
#         print('所有課程')
# Person.role  == getattr(Person,'role')
# Person.show_courses() == getattr(Person,'show_courses')()
# ret = getattr(Person,'show_courses')
# ret()
# 有一個類,有很多靜態屬性,也有很多靜態方法/類方法
# 使用者輸入input任意的屬性名或者方法名,
# 如果是屬性 直接列印  - 用到一個內建函式#getattr(Person,'role')
# 如果是方法 直接呼叫  - 用到一個內建函式#getattr(Person,'show_courses')
# 要求程式不報錯