一、類屬性
類中的屬性:對象屬性、類屬性(類的字段)
1.類屬性
直接定義在類中的變量就是類屬性
類屬性的值不會因為對象不同而不一樣
2.對象屬性
通過 self.屬性名 = 值 定義在init函數(shù)中的屬性
對象屬性的值會因為對象不同而不一樣
class Person:
num = 61
x = 100
print(Person.num)
Person.num = 60
二、對象屬性的增刪改查
class Student:
def __init__(self, name, age=0, gender='男', score=0):
self.name = name
self.age = age
self.gender = gender
self.score = score
def __repr__(self):
return f'<{str(self.__dict__)[1:-1]}>'
stu1 = Student('小明')
stu2 = Student('小花', gender='女')
1.查(獲取屬性的值)
對象.屬性 - 獲取對象指定屬性對應(yīng)的值;屬性不存在會報錯
getattr(對象, 屬性名) - 獲取對象指定屬性對應(yīng)的值;屬性不存在會報錯
getattr(對象, 屬性名, 默認(rèn)值) - 獲取對象指定屬性對應(yīng)的值; 屬性不存在不會報錯,并且返回默認(rèn)值
print(stu1.name)
# print(stu1.name1) # AttributeError: 'Student' object has no attribute 'name1'
print(getattr(stu1, 'name')) # 小明
print(getattr(stu1, 'age')) # 0
# print(getattr(stu1, 'name1')) # AttributeError: 'Student' object has no attribute 'name1'
print(getattr(stu1, 'name', '無名氏')) # 小明
print(getattr(stu1, 'name1', '無名氏')) # 無名氏
# 根據(jù)輸入的內(nèi)容獲取對象屬性的值
# name -> 小明
# age -> 0
# value = input('請選擇(name,age,gender,score):')
# print(getattr(stu1, value))
2.改、增
對象.屬性 = 值 - 當(dāng)屬性不存在就給對象添加屬性,屬性存在的時候就修改指定屬性的值
setattr(對象, 屬性名, 值) - 當(dāng)屬性不存在就給對象添加屬性,屬性存在的時候就修改指定屬性的值
# 屬性存在是修改
stu1.name = 'xiaoming'
print(stu1)
stu1.height = 180
print(stu1) # <'name': 'xiaoming', 'age': 0, 'gender': '男', 'score': 0, 'height': 180>
print(stu1.height)
setattr(stu1, 'age', 18)
print(stu1) # <'name': 'xiaoming', 'age': 18, 'gender': '男', 'score': 0, 'height': 180>
setattr(stu1, 'weight', 80)
print(stu1) # <'name': 'xiaoming', 'age': 18, 'gender': '男', 'score': 0, 'height': 180, 'weight': 80>
print(stu2) # <'name': '小花', 'age': 0, 'gender': '女', 'score': 0>
3.刪
del 對象.屬性 - 刪除對象中指定的屬性
delattr(對象, 屬性名) - 刪除對象中指定的屬性
del stu2.age # <'name': '小花', 'gender': '女', 'score': 0>
print(stu2)
delattr(stu2, 'gender')
print(stu2) # <'name': '小花', 'score': 0>
三、內(nèi)置屬性
# python在定義類的時候系統(tǒng)自動添加的屬性(從基類中繼承下來的屬性)就是內(nèi)置屬性
class Student:
def __init__(self, name, age=18, score=0):
self.name = name
self.age = age
self.score = score
class Dog:
# 類屬性
num = 100
# 對象屬性
def __init__(self, name, age=1, color='白色'):
self.name = name
self.age = age
self.color = color
# 方法
def eat(self, food):
print(f'{self.name}在吃{food}')
@classmethod
def show_num(cls):
print(f'狗的數(shù)量:{cls.num}')
@staticmethod
def bark():
print('狗嗷嗷叫~')
def __repr__(self):
c = self.__class__
m = c.__module__
return f'<{m}模塊.{c.__name__}類的對象: name={self.name},age={self.age},color={self.color}>'
dog1 = Dog('大黃')
1. module
類屬性;
類.module - 獲取定義的模塊的模塊名
print(Dog.__module__)
print(int.__module__)
2.class
對象.class - 獲取對象對應(yīng)的類
c = dog1.__class__
print(c)
print(type(dog1))
print(Dog)
3.name
類.name - 獲取類名
print(Dog.__name__) # 'Dog'
# 重寫 repr 方法, 要求以: <xxx模塊.xxx類的對象: 屬性1=值1,屬性2=值2>
4.dict
類.dict - 將類轉(zhuǎn)換成字典(類的類屬性名作為key,類屬性的值作為值)
對象.dict - 將對象轉(zhuǎn)換成字典(對象屬性名作為key,屬性的值作為值)
print(Dog.__dict__)
print(dog1.__dict__)
5. doc
類.doc - 獲取類的說明文檔
print(list.__doc__)
6.base、bases
類.base - 獲取當(dāng)前類的父類
類.bases - 獲取當(dāng)前類所有的父類
print(Dog.__base__) # <class 'object'>
print(Dog.__bases__) # (<class 'object'>,)
7. slots
class Person:
# __slots__可以約束當(dāng)前類的對象能夠擁有哪些對象屬性
__slots__ = ('name', 'age', 'height')
def __init__(self, name, age=10):
self.name = name
self.age = age
p1 = Person('小明')
# p1.name1 = 'xiaoming'
p1.height = 180
# 注意: 如果給類屬性__slots__賦值了,那么這個類的對象不能再使用__dict__屬性
# print(p1.__dict__)
六、私有化
1.訪問權(quán)限(針對屬性和方法)
公開的:在類的內(nèi)部和外部都可以使用,也能被繼承
保護的:在類的內(nèi)部可以使用,類的外部不能使用,可以被繼承
私有的:只能在類的內(nèi)部使用,不能被繼承
嚴(yán)格來說,python中所有的屬性和方法都是公開的,這兒說的私有化其實是假的私有化
class Person:
num = 100
__num2 = 61
def __init__(self):
self.name = '小明'
self.age = 10
self.__gender = '男'
def eat(self):
print(f'{self.name}在吃飯')
print(self.__gender)
p1 = Person()
print(Person.num)
print(p1.name, p1.age)
p1.eat()
# print(p1.__gender)
# print(Person.__num2)
私有化的原理:
print(p1.__dict__) # {'name': '小明', 'age': 10, '_Person__gender': '男'}
print(p1._Person__gender)
七、getter和setter
1.getter和setter的作用
getter作用:在獲取某個屬性值之前想要做別的事情,就給這個屬性添加getter
setter作用:在給屬性賦值之前想要做別的事情,就給這個屬性添加setter
2.怎么添加getter和setter
1)getter
第一步:在需要添加getter的屬性名前加_
第二步:定義getter對應(yīng)的函數(shù)(1.需要@property裝飾器 2.函數(shù)名就是不帶的屬性名 3.函數(shù)需要一個返回值)
第三步:獲取屬性值的通過: 對象.不帶屬性名 (本質(zhì)就是在調(diào)用getter對應(yīng)的函數(shù),取到屬性值就是函數(shù)的返回值)
2)setter
如果想要給屬性添加setter必須先給屬性添加getter
第一步:添加getter
第二步:定義setter對應(yīng)的函數(shù) (1.需要 @getter函數(shù)名.setter 裝飾器 2.函數(shù)名就是不帶的屬性名 3.需要一個參數(shù)不需要返回值,這個參數(shù)就是嘗試給屬性賦的值)
第三步:給屬性賦值:對象.不帶屬性名 = 值 (本質(zhì)就是在調(diào)用setter對應(yīng)的函數(shù))
class Rect:
def __init__(self, length=0, width=0):
self.length = length
self.width = width
self._area = length*width
@property
def area(self):
print('area屬性值被獲取')
self._area = self.width * self.length
return self._area
@area.setter
def area(self, value):
# print(f'value:{value}')
# self._area = value
raise ValueError
r1 = Rect(4, 5)
print('==========')
print(r1.area)
print('++++++++')
# 不能讓矩形直接修改面積屬性值
# r1.area = 100
# print(r1.__dict__)
#
r1.width = 10
print(r1.area)
r1.length = 10
print(r1.area)
r1.area = 80