1 內置類屬性
-
內置類屬性就是魔法屬性
魔法屬性:屬性名的前面和后面都有兩個下劃線。
魔法方法:方法的前后都有兩個下劃線琉闪。
聲明一個人的類:
class Person:
"""人類"""
# 類的字段
number = 61
def __init__(self, name, age, height):
# 對象的屬性
self.name = name
self.age = age
self.height = height
# 對象方法
def run(self):
print('%s在跑步' % self.name)
# 類方法
@classmethod
def show_number(cls):
print('人類的數(shù)量為%d億' % cls.number)
# 靜態(tài)方法
@staticmethod
def destory():
print("人類在破壞環(huán)境")
實例化一個對象:
p1 = Person('張三', 28, 170)
# 1.__name__屬性 ---> 類的名字(是個字符串)
# 類的屬性
name = Person.__name__
print(name, type(name), type(Person))
# 2.__class__屬性 ---> 獲取對象對應的類(是一個類)
# 對象的屬性
# my_class是一個類,之前類能做的事情他都能做
my_class = p1.__class__
p2 = my_class('小明', 20, 180)
print(Person.__class__)
print(p2.name, my_class.__name__)
# 3.__dict__屬性 ---> 將對象和類的屬性及其對應的值轉換成鍵值對存到一個字典中
print(Person.__dict__) # 字典形式獲取類中的所有內容
print(p1.__dict__)
# 4. __doc__屬性 ---> 獲取類的說明文檔
doc = Person.__doc__
print(doc)
# 5.__module__屬性 ---> 獲取類所在的模塊對應的名字
print(Person.__module__)
print(datetime.datetime.__module__)
# 6.__bass__屬性 ---> 獲取當前類的父類
# 類的屬性
print(Person.__bases__)
2 slots魔法
通過slots中存的元組的屬性的值珠洗,來約束當前這個類的對象的屬性棒卷。對象的屬性只能比元組中的元素少,不能多咒锻!
class Person:
"""人類"""
__slots__ = ('name', 'age', 'face')
def __init__(self):
self.name = '張三'
self.age = 18
self.face = 70
# self.sex = 'boy' # __slots__中并沒有sex
p1 = Person()
p1.sex = 'girl'
#print(p1.sex) # AttributeError: 'Person' object has no attribute 'sex'
注意: 一旦在類中給—__slots__屬性賦了值,那么這個類的對象__dict__屬性就不能使用了
3 屬性的私有化
首先注意:
python中并沒有真正的私有化僻爽!
python的類中默認的屬性和方法都是公開的虫碉。1.私有化
a.類中的屬性和方法都可以通過在屬性名和方法名前加兩個下劃線,來讓屬性和方法變成私有的胸梆。
b.私有的屬性和方法只能在當前的類中使用2.私有化原理
在前面有兩個下劃線的屬性名和方法名前添加了'_類名'來阻止外部通過直接訪問屬性名來使用屬性敦捧。
例如,聲明一個狗類:
class Dog:
"""狗類"""
# 字段
number = 100
__count = 200 # 這里的count就是私有化屬性
def __init__(self):
# 對象的屬性
self.color = '黃色'
self.age = 3
self.name = '大黃'
self.__sex = '公狗' # 私有化sex屬性
# 對象方法
def eat(self):
print('%s在吃狗糧~' % self.name)
# 類方法
@classmethod
def shout(cls):
print('count:', cls.__count, Dog.__count) # 在class內部可以通過類名和cls調用
print('汪汪汪~')
# 靜態(tài)方法
@staticmethod
def function():
print('看家E鼍怠兢卵!')
實例化一個狗對象:
d1 = Dog()
# 在類的外面不能直接使用私有的屬性
# print(Dog.__count)
# print(d1.__sex)
print(d1.__dict__)
print(d1._Dog__sex)
輸出結果為:
{'color': '黃色', 'age': 3, 'name': '大黃', '_Dog__sex': '公狗'}
公狗
4 屬性的getter和setter
1.保護類型的屬性:
a.就只在聲明對象屬性的時候,在屬性名前加一個下劃線绪颖,來代表這個屬性是受保護的屬性秽荤。
那么以后訪問這個屬性的時候就不要直接訪問,要通過getter來獲取屬性的值和setter來給這個屬性賦值柠横。
b.如果一個屬性已經(jīng)聲明成保護類型的屬性窃款,那么我們就需要給這個屬性添加getter。也可以添加setter2.添加getter
添加getter其實就是聲明一個沒有參數(shù)牍氛,有一個返回值的函數(shù)晨继。作用是獲取屬性的值
a.格式:
@property
def 去掉下劃線的屬性名(self):
函數(shù)體
返回值
將屬性相關的值返回
b.使用場景
場景一:如果想要獲取對象的某個屬性的值前,想要干點別的事情搬俊,就可以給這個屬性添加getter
場景二:想要拿到某個屬性被使用的時刻3.添加setter
添加setter就是聲明一個有一個參數(shù)但是沒有返回值的函數(shù)紊扬。作用是給屬性賦值
具體使用方法如下代碼所示:
class Car:
"""車類"""
def __init__(self):
self.color = '黃色'
self.type = '自行車'
# _price屬性是保護類型
self._price = 10000
# 給_price屬性添加getter
@property
def price(self):
print('在使用_price屬性')
return self._price
# 想要給一個屬性添加setter,必須先給這個屬性添加getter
@price.setter
def price(self, price1):
if isinstance(price1, int) or isinstance(price1, float):
self._price = str(price1) + 'K'
else:
self._price = 0
實例化一個類:
c1 = Car()
# print(c1.color, c1.type, c1._price)
#添加完getter后就通過getter去獲取屬性的值
# price就是屬性_price的getter
print(c1.price)
c1.price = 1000
print(c1.price)
c1.price = 'abc'
print(c1.price)
輸出結果為:
在使用_price屬性
10000
在使用_price屬性
1000K
在使用_price屬性
0
5 類的繼承
python中的類可以繼承唉擂,并且支持多繼承餐屎。
程序中的繼承:就是讓子類直接擁有父類的屬性和方法(繼承后父類中的內容不會因為被繼承而減少)
-
1.繼承的語法
class 子類(父類):
類的內容
注意:如果聲明類的時候沒有寫繼承,那么這么類會自動繼承python的基類玩祟,object腹缩。
相當于:class 類名(object)
python中的類都是直接或間接的繼承自object -
2.能繼承哪些東西
a.所有的屬性和方法都能繼承
b.__slots__的值不會繼承,但是會影響子類對象__dict__屬性。不能獲取到父類繼承下來的屬性
具體示例如下所示藏鹊,創(chuàng)建一個人的類作為父類:
class Person(object):
"""人類"""
# 字段
number = 16
# __slots__ = ('name', 'age')
# 對象屬性
def __init__(self, name1='張三', age1=18):
self.name = name1
self.age = age1
self.__heiget = 180
# 對象方法
def show_message(self):
print('姓名:%s胜臊,年齡:%d' % (self.name, self.age))
# 類方法
@classmethod
def show_number(cls):
print('人類的數(shù)量:%d' % cls.number)
# 靜態(tài)方法
@staticmethod
def complaint():
print('人類毆打小動物!')
創(chuàng)建一個學生類伙判,繼承人類,并使用人類的屬性和方法:
class Student(Person):
"""學生類"""
pass
# 創(chuàng)建Person類
p1 = Person()
# 創(chuàng)建學生類
stu1 = Student()
# 類的字段能繼承
print(Student.number)
# 對象的屬性能繼承
print(stu1.name)
stu1.name = '李四' # 能修改
print(stu1.name)
# 對象的方法能繼承
stu1.show_message()
# 類的方法能繼承
stu1.show_number()
# 靜態(tài)方法能繼承
stu1.complaint()
stu1.sex = 'girl'
print(stu1.__dict__)
輸出結果為:
16
張三
李四
姓名:李四黑忱,年齡:18
人類的數(shù)量:16
人類毆打小動物宴抚!
{'name': '李四', 'age': 18, '_Person__heiget': 180, 'sex': 'girl'}
6 方法的重寫
子類繼承父類,擁有父類的屬性和方法以后甫煞,還可以再添加自己的屬性和方法菇曲。
1.添加方法和類的字段
直接在子類中聲明相應的方法和字段2.添加對象屬性
對象的屬性是通過繼承父類的init方法而繼承下來的如果想要在保留父類的對象的同事添加自己的對象屬性,需要在子類的init方法中通過super()去調用父類的方法抚吠。3.方法的重寫
在子類中新實現(xiàn)父類的方法常潮,就是重寫
方式一:直接覆蓋父類的實現(xiàn)
方式二:保留父類的功能再添加其他功能4.類中方法的調用過程
先去當前這個類中去找,沒有去父類中找楷力,找不到再去父類的父類中找喊式,依次類推,如在基類中都沒有找到才崩潰萧朝。在第一次找到的位置去調用岔留。
注意:使用super的時候必須是通過super()來代替父類或者是父類對象
以創(chuàng)建的動物類作為父類,具體實現(xiàn)代碼如下所示:
class Animal:
"""動物類"""
# 動物的基本屬性
def __init__(self):
self.age = 0
self.sex = '雌'
# 動物的共同的行為
def shout(self):
print('嗷嗷叫~')
創(chuàng)建化貓類和狗類繼承自動物類并實例化:
class Cat(Animal):
"""貓類"""
def __init__(self):
# 通過super調用init方法检柬,在貓類的基礎屬性中添加屬性
super().__init__()
self.name = '小花'
food = '魚'
def shout(self):
print('喵喵喵~')
class Dog(Animal):
def shout(self):
# 通過super()調用父類的方法献联,保留父類功能
super().shout()
print('汪汪汪~')
cat1 = Cat()
print(cat1.age)
print(cat1.name)
cat1.shout()
dog1 = Dog()
dog1.shout()
輸出結果為:
0
小花
喵喵喵~
嗷嗷叫~
汪汪汪~
7 運算符的重載
如果希望類的對象支持相應的運算符操作(例如:+、-何址、*里逆、/、>用爪、<等)原押,就必須實現(xiàn)相應的魔法方法。
這個過程就叫運算符的重載项钮。
+:__add__
>:__gt__
一般情況需要對>或者<進行重載班眯,重載后可以通過sort方法直接對對象的列表進行排序。
具體使用方法如下代碼所示:
class Student:
def __init__(self, name='', age=0, score=0):
self.name = name
self.age = age
self.score = score
# self:+前面的對象
# other:+后面的對象
def __add__(self, other):
return self.score + other.score
# 重載 > 符號(大于小于符號重載一次都能用)
def __gt__(self, other):
return self.age > other.age
# 重寫魔法方法__str__烁巫,用來定制對象的打印樣式
def __str__(self):
return 'Student: %s %d %d' % (self.name, self.age, self.score)
實例化人類:
stu1 = Student('小明', 18, 90)
stu2 = Student('小紅', 19, 99)
print(stu1 + stu2)
print(stu1 > stu2)
print(stu1)
輸出結果為:
189
False
Student: 小明 18 90