從入門到入獄------物件導向(二)
class Student:
def __init__(self, name, tel, study_id='001', score=0):
self.name = name
self.tel = tel
self.study_id = study_id
self.score = score
# 在列印一個物件的時候,系統會自動用這個物件去呼叫__repr__方法,並且獲取這個方法的返回值
# 返回值是什麼就列印什麼(返回值必須是字串)
def __repr__(self):
return f'<{str(self.__dict__)[1:-1]}>'
# __dict__將物件轉換成字典
stu1 = Student('小王', 123456, '0001', 1)
stu2 = Student('小林', 22222, '0002', 12)
print(stu1) # <'name': '小王', 'tel': 123456, 'study_id': '0001', 'score': 1>
# 物件屬性的增刪改查
# 查---獲取物件的屬性值
'''
物件.屬性
getattr(物件,屬性名) 可以做到動態獲取屬性值
'''
print(stu1.name) # 小王
# value=input('請輸入要獲取的屬性名:')
# print(getattr(stu2,value)) # value="name" 小林 value="tel" 22222
print(getattr(stu2, 'height', 180)) # 180 獲取不存在的屬性如果不給預設值會報錯,
# 增/改
'''
物件.屬性=值 屬性存在的時候就是修改,屬性不存在的時候就是增加
setattr(物件,屬性名,值) 可以做到動態增加/修改屬性值
'''
stu1.name = '我不是小王'
stu1.height = '新新增的屬性:身高170'
print(stu1) # <'name': '我不是小王', 'tel': 123456, 'study_id': '0001', 'score': 1, 'height': '新新增的屬性:身高170'>
setattr(stu1, 'name', '我還是小王')
print(stu1) # <'name': '我還是小王', 'tel': 123456, 'study_id': '0001', 'score': 1, 'height': '新新增的屬性:身高170'>
# 刪
'''
del 物件.屬性 刪除屬性
del 物件 刪除物件
delattr(物件,屬性名)
'''
del stu1.height
print(stu1) # <'name': '我還是小王', 'tel': 123456, 'study_id': '0001', 'score': 1>
delattr(stu1, 'study_id')
print(stu1) # <'name': '我還是小王', 'tel': 123456, 'score': 1>
物件方法:
定義:直接定義
呼叫:物件.方法名()
特點:有個預設引數self,這個引數在呼叫的時候不用傳參,系統會自動將當前物件傳給self
使用:如果實現函式的功能需要用到物件,那麼這個函式就定義成物件方法
類方法:
定義:在定義函式前加@classmethod
呼叫:類.方法名()
特點:有個預設引數cls,這個引數在呼叫的時候不用傳參,系統會自動將當前類傳給cls
使用:如果實現函式的功能不需要物件需要用到類,那麼這個函式就定義成類方法
靜態方法
定義:在定義函式前加@staticmethod
呼叫:類.方法名()
特點:沒有預設引數
使用:實現函式功能不需要物件也不需要類的前提下就定義靜態方法
class Student:
# func1是物件方法
def func1(self):
print('物件方法')
# func2是類方法
@classmethod
def func2(cls):
print('cls:', cls) # cls:<class '__main__.Student'>
# 當前類能做的,cls都可以做
# func3是靜態方法
@staticmethod
def func3():
print('靜態方法')
print('Student:', Student) # Student: <class '__main__.Student'>
class Person:
"""
人類
"""
num = 61
def __init__(self, name='張三', age=18, gender='男'):
self.name = name
self.age = age
self.gender = gender
def eat(self, food='麵條'):
print(f'{self.name}在吃{food}')
@classmethod
def message(cls):
print(f'人類目前的數量是:{cls.num}')
@staticmethod
def destroy():
print('人類破壞環境')
p1 = Person()
# 類屬性
'''
類名.__doc__ 獲取類的說明文件
print(Person.__doc__) # 人類
類名.__module__ 獲取指定類所在的模組 如果結果是__main__ 說明是當前模組
print(Person.__module__) # __main__
print(list.__module__) # builtins
物件.__class__ 獲取指定物件對應的型別,和type(物件)功能一樣
print(p1.__class__) # <class '__main__.Person'>
print(type(p1)) # <class '__main__.Person'>
類名.__name__ 獲取類名型別為str
print(Person.__name__) # 'Person'
print(int.__name__) # 'int'
類名.__dict__ 獲取類所有的欄位和欄位值,轉化為字典,key是欄位名,value是欄位的值
print(Person.__dict__)
物件.__dict__ 獲取物件所有的屬性和屬性值,轉化為字典,key是屬性名,value是屬性的值
print(p1.__dict__) # {'name': '張三', 'age': 18, 'gender': '男'}
類名.__base__ 獲取指定類的父類
類名.__bases__ 獲取類所有的父類
object是python中所有類的基類
print(Person.__base__) # <class 'object'>
print(Person.__bases__) # (<class 'object'>,)
'''
# 根據資料不同的型別建立以該型別名命名的檔案
datas = ['abc', -0.1234, '你好', 564]
for data in datas:
with open(rf'files\{data.__class__.__name__}.txt', 'a', encoding='utf-8') as f:
f.write(str(data) + '\n')
getter
使用:在獲取物件屬性前,如果要做別的什麼事就可以給這個屬性新增getter
用法:
在需要新增getter的屬性名前加_
在裝飾器@property後面定義一個函式,函式名就是屬性名去掉_
函式沒有引數,但是需要一個返回值,返回值就是獲取屬性值得到的結果
通過物件獲取屬性的時候,屬性不需要帶_
class Circle:
pi = 3.14
def __init__(self, r=10):
self.r = r
@property
def area(self):
return Circle.pi * self.r ** 2
c1 = Circle(100)
print(c1.area)
練習,給Person新增屬性,要求:age中儲存年齡值,但是獲取age屬性的時候
得到的是:兒童(0-4),少年(5-12),青年(13-28),壯年(29-40)中年(41-55),老年(55以上)
class Person:
def __init__(self, age=0, name='張三', gender='男'):
self.name = name
self._age = age
self.gender = gender
@property
def age(self):
if 0 <= self._age <= 4:
return '兒童'
elif 5 <= self._age <= 12:
return '少年'
elif 13 <= self._age <= 28:
return '青年'
elif 29 <= self._age <= 40:
return '中年'
else:
return '老年'
setter —新增之前必須新增getter
’
給物件屬性賦值的之前做別的事情,就給這個屬性新增setter
用法
在裝飾器 @函式名.setter 後面定義一個函式,函式名就是屬性名去掉_
函式有且只有一個引數(這個引數指向的是賦值的時候賦的值)
@age.setter
def age(self, value):
print(value)
if type(value) != int:
raise ValueError
if value < 0 or value > 150:
raise ValueError
p1 = Person()
# p1.age='dwa' ValueError
# p1.age=151 ValueError
訪問許可權
公開的:公開的屬性和方法在類的內部外部都能用,並且可以被繼承
保護的:保護的屬性和方法在類的內部可以使用,外部不能用,但是可以繼承
私有的:私有的屬性和方法在類的內部可以使用,外部不能用,不能被繼承
python中的屬性和方法只有訪問許可權:公開的
python 所謂的私有化只是一種說明提示
私有化的方法:
在屬性名和方法名前加__(只能是兩個__開頭,不能再__結尾)
class Person:
num = 100
__info = '動物'
def __init__(self, name='張三', age=18, gender='男'):
self.name = name
self.age = age
self.gender = gender
def func1(self):
return Person.__info
def __func2(self):
return Person.num
p1 = Person()
print(p1.func1()) # 動物
print(Person.num) # 100
# print(Person.__info) # AttributeError: type object 'Person' has no attribute '__info'
# print(p1.func2()) # AttributeError: 'Person' object has no attribute 'func2'
# print(Person._Person__info) # 動物 強行檢視
運算子
python在使用運算子的時候,本質是在呼叫運算子對應的方法
每個運算子對應的方法的方法名是固定的,不同型別的資料在參與相同運算的時候
會呼叫不同類中對應方法
某個型別的資料是否支援某種運算,就看這個資料對應的型別中有沒有實現這個運算子對應的方法
# __add__
class Person:
def __init__(self, age=0, name='?', gender='男'):
self.name = name
self._age = age
self.gender = gender
#self指向+前面的資料,other指向+後面的資料
def __add__(self, other):
return self.name + other.name
def __mul__(self, other):
return [self.name for _ in range(len(other.name))]
def __repr__(self):
return f'<{str(self.__dict__)[1:-1]}>'
def __gt__(self, other1):
return self._age>other1._age
p1 = Person(56,'王五','男')
p2 = Person(1, "小花",'女')
print(p1 + p2) # 張三李四 本質是:pi.__add__(p2)
print(p1 * p2) # ['張三', '張三'] 本質是:pi.__mul__(p2)
# 練習 根據年齡排序
p3=Person(20,'張三','男')
p4=Person(25,'老王','男')
# 方法一 過載 > 運算子
ps=[p1,p2,p3,p4]
print(sorted(ps))
# 方法二 實參高階函式
ps.sort(key=lambda item :item._age)
print(ps)
相關文章
- JavaScript物件導向入門JavaScript物件
- 從程式導向到物件導向物件
- Java入門教程八(物件導向)Java物件
- python-物件導向入門Python物件
- 【3】python入門-物件導向-2Python物件
- ActiveMQ從入門到精通(二)MQ
- 物件導向程式設計入門 - Janos Pasztor物件程式設計
- 從物件導向到模式再到真正的物件導向 (轉)物件模式
- python物件導向入門(1):從程式碼複用開始Python物件
- Go 語言極速入門4 - 物件導向Go物件
- FQ:從入門到放棄(二)
- Linux從入門到精通(二)Linux
- scala 從入門到入門+
- makefile從入門到入門
- Python專案案例開發從入門到實戰-1.3 Python物件導向設計Python物件
- 物件導向-由淺入深物件
- JS基礎入門篇(三十六)—物件導向( 三 )JS物件
- 從零學Python:第十六課-物件導向程式設計入門Python物件程式設計
- vue+webpack 從入門到精通(二)VueWeb
- Python基礎入門(6)- 物件導向程式設計Python物件程式設計
- C#快速入門教程(1)——物件導向程式設計C#物件程式設計
- javascript快速入門12--函式式與物件導向JavaScript函式物件
- 物件導向JavaScript入門——來自Mozilla的官網教程物件JavaScript
- 全網最適合入門的物件導向程式設計教程:00 物件導向設計方法導論物件程式設計
- AOP埋點從入門到放棄(二)
- Java基礎01 從HelloWorld到物件導向Java物件
- 從 Java 到 Scala(一):物件導向談起Java物件
- MyBatis從入門到精通(一):MyBatis入門MyBatis
- kafka從入門到關門Kafka
- koa2 從入門到進階之路 (二)
- Docker 實戰教程之從入門到提高(二)Docker
- Docker 從入門到精通(二) 搭建本地倉庫Docker
- ButterKnife 從入門到精通 - 原始碼級分析(二)原始碼
- vue從入門到進階:指令與事件(二)Vue事件
- .NET8 Blazor 從入門到精通:(二)元件Blazor元件
- 從入門到精通,Java學習路線導航Java
- Thymeleaf從入門到精通
- LESS從入門到精通