
目錄
import time
def init_str_del():
class Teacher(object):
# 類屬性:在方法外、類內(nèi)部定義的屬性
# 對象沒創(chuàng)建的時(shí)候就想使用一個(gè)屬性 那么就可以定義一個(gè)類屬性
country = "中國"
# 隱匿的添加對象屬性
# 實(shí)例屬性:在init方法內(nèi)定義的屬性
def __init__(self,name,age):
self.name = name
self.age = age
# 輸出對象的時(shí)候,不想看到對象的內(nèi)存地址,那么魔法方法__str__可以返回對象的描述信息
def __str__(self):
# 返回一個(gè)字符串信息
return '我叫:%s 年齡:%d' % (self.name, self.age)
# 1.程序退出,程序中所使用到的對象全部銷毀
# 2.當(dāng)前對象的內(nèi)存地址沒有變量使用的時(shí)候,那么對象銷毀
def __del__(self):
print('對象被釋放了:', self)
def show_info(self):
print("python3里的舊式類自動繼承object")
print(self.name, self.age)
teacher = Teacher('鄧川', 21)
teacher.show_info()
'''################### 類屬性的操作 ###################'''
# 訪問類屬性
print(Teacher.country)
# 使用類不能訪問對象屬性
# print(Teacher.age)
# 修改類屬性
Teacher.country = '中國0'
print(Teacher.country)
# 查看類屬性和方法
print(Teacher.__dict__)
'''################### 實(shí)例屬性的操作 ###################'''
print(teacher.name)
# 對象可以訪問類屬性
print(teacher.country)
# 對象不能修改類屬性,其實(shí)是添加了一個(gè)對象屬性
print("-" * 20)
print(Teacher.__dict__)
print(teacher.__dict__)
teacher.country = '中國人1'
print(teacher.country)
print(Teacher.__dict__)
print(teacher.__dict__)
# 其實(shí)記住一個(gè)原則就好,類屬性由類去操作,實(shí)例屬性由對象去操作就不會出錯!??!
# 對象可以訪問類屬性 不能修改
print(teacher.__dict__)
# 使用實(shí)例修改對象屬性
teacher.name = '李四'
print(teacher.name)
print(teacher.__dict__)
'''################### 靜態(tài)動態(tài)添加屬性 ###################'''
# 沒有init方法的時(shí)候,可以動態(tài)的添加對象屬性
teacher.name = '李四'
teacher.age = 18
teacher.show_info()
# 可以修改屬性
teacher.name = '王五'
print(teacher.name, teacher.age)
# 查看Teacher類繼承的父類
print(Teacher.__bases__)
'''################### __str__方法 ###################'''
# 輸出對象 自動調(diào)用__str__方法
print(teacher)
'''################### __del__方法 ###################'''
# 刪除變量 => 對象先釋放再退出 (第2種)
del teacher
# => 程序退出了對象再被釋放(第1種)
# teacher0 = teacher
# del teacher
# 引用計(jì)數(shù):內(nèi)存地址被變量使用的次數(shù),當(dāng)引用計(jì)數(shù)為0 表示對象被銷毀
time.sleep(3)
print('程序退出了')
def single_inherit():
class Animal(object):
# 對象方法
def run(self):
print("動物跑起來了")
class Dog(Animal):
# 重寫:子類繼承父類,父類的方法滿足不了子類的需要可以對父類的方法進(jìn)行重寫
# 重寫的特點(diǎn):1.繼承關(guān)系 2.方法名相同
def run(self):
print("小狗跑起來了")
def wang(self):
# 在此調(diào)用父類的方法
# <1>self,前提:當(dāng)前類里面沒有父類的方法,否則調(diào)用的是當(dāng)前類里面的方法,因?yàn)橹貙懥? self.run()
# <2>使用父類的類名 如果使用類名調(diào)用對象方法需要傳入實(shí)例對象
Animal.run(self)
# <3>super調(diào)用父類的方法
# 根據(jù)指定類,在類繼承鏈中獲取下一個(gè)類
# 提示:1.Dog表示根據(jù)指定類找類繼承鏈中獲取下一個(gè)類
# 2.self表示獲取self對象類型的類繼承鏈
# 3.super不一定是你直接繼承的父類?。?!單繼承直接理解成是繼承的父類沒有問題,但是多繼承就有可能不是
# 4.super調(diào)用的是父類的方法,但是不一定是你直接繼承父類的方法
super(Dog, self).run()
print(self.__class__.mro())
print('汪')
# 在python里面的方法調(diào)用會遵循mro,類繼承順序,也就是在某個(gè)類里找到了就不會再找了
# print(Dog.mro())
dog = Dog()
dog.wang()
dog.run()
def more_inherit():
class A(object):
def show_a(self):
print('我是A類')
class B(object):
def show_b(self):
print('我是B類')
class C(A,B):
def show(self):
# 查看類的繼承順序
print(self.__class__.mro())
# 指定類A要在self對象類繼承順序中找下一個(gè)類
super(A,self).show_b()
print('我是C類')
# super(C,self).show_b()也是可以的?。?!因?yàn)橛欣^承關(guān)系!輸出結(jié)果是一樣的
C().show()
def init_inherit():
class A():
def __init__(self,name):
print("A")
self.name = name
class B(A):
# 提示:如果子類提供了調(diào)用的方法,那么不會主動調(diào)用父類的方法
def __init__(self, subject):
# 調(diào)用父類的__init__方法
# self.__init__('DC') 這種寫法錯誤 因?yàn)榉椒粯?在這會遞歸
# 使用類名調(diào)用父類的init方法
A.__init__(self, '李四')
# super調(diào)用父類里面的init
super(B,self).__init__('王五')
# 簡寫 super() -> super(B,self)
super().__init__('小明')
print("B")
self.subject = subject
def show(self):
print("我是B類")
b = B("PYTHON")
print(b.subject)
print(b.name)
b.show()
def rewrite_super():
class Person(object):
def show(self):
print('我是人類')
class Plane(object):
def show(self):
print('飛機(jī)')
def fly(self):
print('飛機(jī)可以飛')
class Student(Person,Plane):
def show(self):
print(self.__class__.mro())
# 方法重寫也可以使用super,調(diào)用父類的方法
super(Person,self).show()
dc = Student()
dc.show()
def private_attributes_method():
# 在屬性名和方法名加上 兩個(gè)下劃線 '__' 那么定義的屬性和方法就是私有屬性和私有方法
class Person(object):
def __init__(self,name,age):
self.name = name
# 私有屬性,只能在本類內(nèi)部使用,在類外面不能使用
# 注意點(diǎn):私有屬性只能在init方法里面添加
self.__age = age
def show(self):
# 在類內(nèi)部使用私有屬性和私有方法是可以的
print(self.name, self.__age)
self.__money()
def __money(self):
print("100萬")
person = Person('DC', 20)
print(person.name)
# 私有屬性在外界訪問不了
# print(person.__age)
person.show()
# 私有方法在外界訪問不了
# person.__money()
# 查看對象中的屬性信息
print(person.__dict__)
# 本意是修改私有屬性
# 在這里不是修改了私有屬性,而是給對象添加了一個(gè)__age的對象屬性
# 提示:這里也不是添加的私有屬性,只能在init方法里面添加
person.__age = 22
print(person.__age)
print(person.__dict__)
# 查看類屬性和方法
print(Person.__dict__)
# 在python里面私有屬性和私有方法沒有做到絕對的私有,只是進(jìn)行了一個(gè)名字的偽裝
# 非常規(guī)操作 不建議這樣使用
print(person.__dict__)
print(person._Person__age)
person._Person__age = 34
print(person.__dict__)
print(person._Person__age)
person._Person__money()
person.show()
def inherit_private():
class Person(object):
def __init__(self):
self.__age = 18
def __show(self):
print('我是一個(gè)私有方法')
class Student(Person):
# def show(self):
# print(student.__age)
# student.__show()
pass
student = Student()
# print(student.__age)
# student.__show()
# student.show()
# 總結(jié):子類繼承父類,不能直接使用父類的私有屬性和私有方法
def classMethod_staticMethod():
class Person(object):
# 私有類屬性
__mytype = '黃種人'
def __init__(self):
self.name = 'zww'
# 定義對象方法:在方法的參數(shù)里面有self表示對象方法
def show(self):
print('我是人類')
# 定義類方法 cls表示當(dāng)前類
@classmethod
def show_info(cls):
print(cls)
print('我是一個(gè)類方法')
# 定義靜態(tài)方法 提示:靜態(tài)方法和當(dāng)前對象和當(dāng)前類沒有關(guān)系,不會使用self和cls
@staticmethod
def show_msg():
print('我是一個(gè)靜態(tài)方法')
# 應(yīng)用場景:用類方法可以修改類屬性
@classmethod
def set_type(cls, mytype):
cls.__mytype = mytype
# 返回一個(gè)類的私有屬性
@classmethod
def get_type(cls):
return cls.__mytype
# ----------------------------------對象方法是最通用的方法,可以修改對象屬性和類屬性
def instance_set_type(self, mytype,name):
# self.__mytype = mytype 不要這樣寫,這樣寫就添加了一個(gè)對象屬性
# self.__class__ 獲取對象所對應(yīng)的類
self.__class__.__mytype = mytype
print(self.name)
# 修改對象屬性
self.name = name
# 獲取對應(yīng)的類屬性
def instance_get_type(self):
print(self.name)
return self.__class__.__mytype
# ---------------------------------------------------既不需要當(dāng)前對象也不需要當(dāng)前類
@staticmethod
def sum_num(num1, num2):
return num1 + num2
p = Person()
p.show()
p.show_info()
p.show_msg()
p.set_type('白種人')
result = p.get_type()
print(result)
p.instance_set_type('黑種人','DC')
print(p.instance_get_type())
print(p.sum_num(1, 2))
# 類調(diào)用靜態(tài)方法和類方法不需要傳入當(dāng)前類,如果類調(diào)用對象方法需要傳入一個(gè)實(shí)例
Person.show_msg()
# Person.show(p) # 一般都不這樣干
Person.show_info()
def polymorphism():
# 多態(tài): 關(guān)注的是同一個(gè)方法,但是會出現(xiàn)不同的表現(xiàn)形式,在python里不需要關(guān)注類型
class Text(object):
def show(self):
print('顯示文字')
class Image(object):
def show(self):
print('顯示圖片')
class Video(object):
def show(self):
print('顯示視頻')
class Person(object):
def show(self):
print('我在跳舞')
# 實(shí)現(xiàn)顯示數(shù)據(jù)的功能
def show_data(data):
# 關(guān)心的是 同一個(gè) 方法,會出現(xiàn)不同的表現(xiàn)形式,那么這種操作叫做多態(tài)
# 在python里面多態(tài):只關(guān)心對象的方法,不關(guān)心對象的類型
data.show()
image = Image()
video = Video()
p = Person()
show_data(p)
def new():
# 單例:在應(yīng)用程序中不管創(chuàng)建多少次對象只有一個(gè)實(shí)例對象 內(nèi)存地址是一樣的
class Person(object):
# 私有的類屬性
__instance = None
# 創(chuàng)建對象
def __new__(cls, *args, **kwargs):
# if cls.__instance == None:
if not cls.__instance:
print("創(chuàng)建對象")
# 把創(chuàng)建的對象給類屬性
cls.__instance = object.__new__(cls)
return cls.__instance
def __init__(self,name,age):
print('初始化')
self.name = name
self.age = age
p1 = Person('張三', 20)
# p1對象已經(jīng)創(chuàng)建了,在這里返回已經(jīng)創(chuàng)建的對象的內(nèi)存地址,然后對P2對象進(jìn)行初始化
# p1、p2的內(nèi)存地址是一樣的 p2初始化的內(nèi)容覆蓋了p1初始化的內(nèi)容
p2 = Person('李四', 22)
print(p1, p2)
print(p1.name, p2.name) # 李四 李四
def slots():
# 指明創(chuàng)建對象的時(shí)候不能再添加其它屬性,只能是指定的屬性
class Student(object):
# 這樣的操作可以讓對象的屬性固定
__slots__ = ('name', 'age')
def __init__(self,name,age):
self.name = name
self.age = age
stu = Student('xx', 20)
print(stu.name,stu.age)
stu.name = '李四'
stu.age = 21
# stu.sex = '女'
print(stu.name,stu.age)
def method_to_variable():
'''
class Student(object):
def __init__(self):
self.__score = 100
def set_score(self, score):
self.__score = score
def get_score(self):
return self.__score
stu = Student()
score = stu.get_score()
print(score)
stu.set_score(99)
score = stu.get_score()
print(score)
'''
class Student(object):
def __init__(self):
self.__score = 100
# 把方法改成對應(yīng)的屬性
# 獲取值
@property
def get_score(self):
return self.__score
# 設(shè)置值
@get_score.setter
def set_score(self, score):
self.__score = score
stu = Student()
score = stu.get_score
print(score)
stu.set_score = 80
score = stu.get_score
print(score)
if __name__ == '__main__':
# variable靜態(tài)動態(tài)的添加 魔法方法str和del
init_str_del()
# 單繼承 使用類名調(diào)用父類的方法
single_inherit()
# 多繼承 super的使用
more_inherit()
# __init__方法中使用super
init_inherit()
# 在重寫方法中使用super
rewrite_super()
# 私有屬性和私有方法
private_attributes_method()
# 子類不能直接使用父類的私有屬性和私有方法
inherit_private()
# 類方法和靜態(tài)方法
classMethod_staticMethod()
# 多態(tài)
polymorphism()
# 單例
new()
# 指明創(chuàng)建對象的時(shí)候不能再添加其它屬性,只能是指定的屬性
slots()
# 把方法改成對應(yīng)的屬性
method_to_variable()