作者:Java學術趴 倉庫:Github、Gitee ️博客:CSDN、掘金、InfoQ、雲+社區 特別聲明:原創不易,未經授權不得轉載或抄襲,如需轉載可聯系小編授權。 版權聲明:文章裡的部分文字或者圖片來自於互聯網以及百度百科,如有侵權請盡快聯系小編。
️每日毒雞湯:這個社會是存在不公平的,不要抱怨,因為沒有用!人總是在反省中進步的!
大家好!我是你們的老朋友Java學術趴。
給類的實例對象添加額外屬性
# 動態添加屬性和方法
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
pass
# 創建一個類實例對象
student = Student('小明', 30)
# 使用類實例對象原有的屬性
print(student.name)
# 動態添加實例對象屬性。此時並不是給類添加了這個room屬性
# 此時只是給這個對象添加了額外的room屬性,其他的實例對象不會有這個room屬性
student.room = 'python二班'
print(student.room)
# python二班
student2 = Student('小王', 40)
# student2沒有room屬性,student只是給自己添加了額外的room屬性
# print(student2.room) 報錯
復制代碼
給類添加額外屬性
# 動態添加屬性和方法
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
pass
# 給類添加屬性。通過類進行點
Student.height = '175'
# 實例對象可以訪問類屬性。
# 實例對象可以訪問類屬性以及實例屬性
# 類只能訪問類屬性,不可以訪問實例屬性
student = Student('張三', 30)
print(student.height)
# 175
復制代碼
動態添加實例方法:需要使用types
# 動態添加屬性和方法
# 導入添加方法的庫
import types
# 定義動態添加的實例對象方法
# 定義的實例對象的方法必須存在 self 這個參數,否則在綁定的時候會報錯
# 即使方法體中用不到這個 self 參數,這裡也不可以省略
def show(self):
print('{}的身高是:{}kg,班級是:{}'.format(self.name, self.height, Student.room))
print(1)
pass
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
pass
student = Student('小明', 20)
# 動態添加實例對象屬性
student.height = '175'
# 動態添加類屬性
Student.room = 'python一班'
# 給實例對象動態添加方法。
# 首先需要通過types.MethodType綁定方法,第一個參數是綁定的方法名,第二個是實例對象名
student.showInfo = types.MethodType(show, student)
# 調用動態綁定的實例方法
student.showInfo()
# 小明的身高是:175kg,班級是:python一班
# 1
student1 = Student('小王', 30)
# 此時給實例對象添加額外的方法,只是給student進行了添加,student1需要再次進行綁定
# student1.showInfo() 報錯
復制代碼
動態添加類方法和靜態方法:類名.方法名 = xxx 形式綁定類方法
# 動態添加屬性和方法
# 導入添加方法的庫
import types
# 定義一個類方法
# 這個類方法必須存在 cls 這個參數,不論方法體有沒有用到,都必須給定這個參數
# 否則在綁定方法的時候會報錯
@classmethod
def eat(cls):
print('吃飯')
pass
# 定義一個靜態方法
# 靜態方法,這個 cls 參數可有可無
@staticmethod
def drink():
print('喝水')
pass
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
pass
student = Student('小明', 30)
# 給Student類綁定類方法eat()
Student.eat = eat
# 調用額外添加的類方法
# 這裡的參數不能傳遞,如果給了會報錯
Student.eat()
# 吃飯
# 給Student類綁定額外的靜態方法
Student.drink = drink
Student.drink()
# 喝水
# 實例對象可以訪問到額外添加的類方法和類靜態方法
student.eat()
student.drink()
復制代碼
使用方式
# 通過 __slots__ 控制添加的額外實例屬性還有類屬性
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
# 如果不把name以及age屬性添加到這個 __slots__,那麼此時name和age為只讀屬性,不可以從新賦值
# 在創建對象的時候就無法給name和age賦值,所以這裡必須把這兩個參數寫上
__slots__ = ('sex', 'room', 'name', 'age')
pass
student = Student('小明', 20)
print(student.name)
print(student.age)
# 添加額外的實例屬性並且是__slots__中存在的
student.sex = '男'
print(student.sex)
# 男
# 添加額外的實例屬性,是__slots__中不存在的
# student.height = '186' 報錯
# 給類添加額外的屬性並且是 __slots__ 中存在的
Student.sex = '男'
print(Student.sex)
# 男
# 添加額外的實例屬性,是__slots__中不存在的
# student.height = '186' 報錯
# 如果不存在 __slots__ ,那麼所有的實例屬性都會存儲在一個字典中。字典是非常占用內存空間的
# 當存在 __slots__ 的時候,所有的實例屬性就不會存儲到這個字典中,而是把屬性存儲到 __slots__ 變量中
print(student.__dict__)
# {'name': '小明', 'age': 20, 'sex': '男'}
復制代碼
slots變量在父子類之間的繼承
子類必須聲明 slots 變量才會繼承父類的,否則不會繼承
# 通過 __slots__ 控制添加的額外實例屬性還有類屬性
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '姓名:{},年齡:{}'.format(self.name, self.age)
# 如果不把name以及age屬性添加到這個 __slots__,那麼此時name和age為只讀屬性,不可以從新賦值
# 在創建對象的時候就無法給name和age賦值,所以這裡必須把這兩個參數寫上
__slots__ = ('sex', 'room', 'name', 'age')
pass
class Student(People):
pass
student = Student('小李', 18)
# 當子類沒有聲明 slots 變量的時候不會繼承父類的 slots 變量
# 此時可以給子類隨意動態添加屬性值
student.height = '165'
print(student.height)
# 165
class Teacher(People):
# 子類聲明 slots 變量,此時會繼承父類的並且可以添加額外的屬性
# 子類盡量不要去重寫父類已經存在的屬性。重復聲明會占用內存空間
__slots__ = 'weight'
pass
teacher = Teacher('王老師', 40)
# 繼承父類中 slots變量 中的屬性
print('教師的姓名:{},教師的年齡:{}'.format(teacher.name, teacher.age))
# 教師的姓名:王老師,教師的年齡:40
# 此時子類繼承了父類的 slots 變量,就不可以隨意的添加屬性了
# teacher.height = '175' 報錯,因為slots中不存在height屬性
# 可以添加 slots 中存在的屬性值
teacher.weight = '50'
print(teacher.weight)
# 50