程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python干貨——_ _slots__屬性

編輯:Python

作者:Java學術趴 倉庫:Github、Gitee ️博客:CSDN、掘金、InfoQ、雲+社區 特別聲明:原創不易,未經授權不得轉載或抄襲,如需轉載可聯系小編授權。 版權聲明:文章裡的部分文字或者圖片來自於互聯網以及百度百科,如有侵權請盡快聯系小編。

️每日毒雞湯:這個社會是存在不公平的,不要抱怨,因為沒有用!人總是在反省中進步的!

大家好!我是你們的老朋友Java學術趴。

第二十章 動態添加屬性和方法

20.1 概念

  • 動態語言:運行時可以改變其結構的語言,例如新的函數、對象、甚至代碼可以被引入,已有的函數可以被刪除或是其他結構上的變化。如php、js、python都是動態語言,C、C#、Java都是靜態語言。所以python可以在程序運行過程中添加屬性和方法。

20.2 動態添加屬性

給類的實例對象添加額外屬性

# 動態添加屬性和方法
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
復制代碼

20.3 動態添加方法

動態添加實例方法:需要使用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__屬性

21.1 概念

  • python是動態語言,在運行的時候可以動態添加屬性。如果是限制在運行時候給類添加屬性,Python允許在定義class的時候,定義一個特殊的_ _slots__變量,來限制該class實例能添加的屬性。
  • 只有在_ _slots__變量中的屬性才能添加,沒有在slots變量中的屬性添加失敗。可以防止其他人在調用類的時候胡亂添加啊屬性或方法。只有子類聲明 slots 的時候,才會繼承父類的slots。如果子類不聲明slots變量則不會進行繼承

使用方式

# 通過 __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

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved