1.什么是內置類屬性
聲明類的時候系統(tǒng)自動添加的屬性(可能是字段也可能是對象屬性)
import json
class Person:
"""
說明文檔: 人類
num - 人類的數(shù)量
name - 人的名字
"""
num = 61
# 注意: 如果設置了__slots__的值滥朱,那么當前類的對象就不能使用__dict__屬性
# __slots__ = ('name', 'gender', 'age')
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def eat(self,food):
print('%s在吃%s' % (self.name, food))
定制當前類的對象的打印
- 重寫str方法, 這個方法的返回值就是對應的打印結果(類型必須是字符串)
def __str__(self):
# return '姓名:{}, 年齡:{}, 性別:{}'.format(self.name, self.age, self.gender)
return '<'+str(self.__dict__)[1:-1]+'>'
2)重寫 repr方法,這個方法的返回值就是對應的打印結果(類型必須是字符串)
def __repr__(self):
# return '姓名:{}, 年齡:{}, 性別:{}'.format(self.name, self.age, self.gender)
# <'name': '小明', 'gender': '男', 'age': 18>
return '<' + str(self.__dict__)[1:-1] + '>'
# return 'abc'
p1 = Person('小明', '男', 18)
# 1.__name__
類的字段; 類.name - 獲取類的名字(字符串)
print(type(Person), Person)
print(type(int))
print(Person.__name__)
2.doc
類的字段; 類.doc - 獲取類的說明文檔
print(Person.__doc__)
print(int.__doc__)
3.class
對象屬性; 對象.class - 獲取對象對應的類,返回的是類
(和type(對象)功能一樣)
print(p1.__class__)
print(type(p1))
# type1 = p1.__class__
type1 = type(p1)
print(type1.__name__)
p2 = type1('小花', '女', 17)
print(p2.name, p2.gender, p2.age)
4.dict (將對象轉換成字典)
對象屬性; 對象.dict - 將對象所有的屬性和對應的值轉換成一個字典中的鍵值對(一個對象對應一個字典)
類的字段; 類.dict - 將類轉換成一個字典,字典中的元素是類中所有的字段和對應的值
print(p1.__dict__)
print(Person.__dict__)
print('p1:', p1)
print('p2:', p2)
persons = [p1, p2]
print(persons)
-
module
類的字段; 類.module - 獲取當前類是在哪個模塊中聲明的(返回的是模塊的名字)
print(Person.__module__)
print(bool.__module__)
6.bases
類的字段; 類.bases - 獲取當前類的父類(返回的是一個元祖)
print(Person.__bases__)
練習: 將字典轉換成對象
with open('data', 'r', encoding='utf-8') as f:
content = json.loads(f.read())
datas = content['data']
class Data:
def __init__(self, dict1: dict):
for key in dict1:
setattr(self, key, dict1[key])
def __repr__(self):
return '<'+str(self.__dict__)[1:-1]+'>'
for item in datas:
data = Data(item)
print(data.name, type(data))
# print(data)
1.什么是繼承
繼承就是讓子類直接擁有父類的屬性和方法
子類 - 繼承者
父類/超類 - 被繼承者
2.怎么繼承
1)語法
class 類名(父類1,父類2,..):
說明文檔
類的內容
2)說明:
() - 固定寫法背蟆,如果省略相當于(object)
聲明類的時候如果沒有寫父類肪虎,默認繼承object(object又叫基類)
父類 - 一個類的父類可以有多個劣砍,但是一般情況下只有一個(支持多繼承)
class Person:
num = 61
def __init__(self):
print('Person中init')
self.name = '小明'
self.age = 18
self.gender = '男'
self.__a = 10
def eat(self, food='米飯'):
print('{}在吃{}'.format(self.name, food))
@classmethod
def show(cls):
print('人類的數(shù)量:%d' % cls.num)
@staticmethod
def func1():
print('人類')
def func2(self):
print('我是'+self.name)
class Student(Person):
num = 10
def __init__(self):
# 在子類中添加對象屬性,需要先通過super()去調用父類的__init__來繼承父類的對象屬性
super().__init__()
print('Student中init')
self.study_id = '001'
self.class1 = 'py1904'
# 添加功能
def study(self):
print(self.name+'在好好學習!')
@staticmethod
def func1():
print('學生')
def func2(self):
print('我是學生!')
# 在子類中可以通過super()可以去調用父類的方法
# 注意: super()只能在對象方法和類方法中使用
super().func2()
stu1 = Student()
print(Student.num)
print(stu1.name, stu1.age, stu1.gender)
stu1.eat()
Student.show()
print(stu1.__dict__)
Student.func1()
stu1.func2()
1.什么是getter和setter
當我們需要在獲取屬性值之前做點別的事情就需要給這個屬性添加getter扇救;
當需要給屬性賦值之前做別的事情刑枝,就需要給這個屬性添加setter
2.給屬性添加getter
- 屬性命名的時候前面加'_'
- 在@property裝飾器的后面聲明一個對象方法
a.將屬性去掉下劃線作為方法名
b.方法除了self以外不需要其他參數(shù)
c.函數(shù)的返回值就是獲取這個屬性的時候得到的值 - 在外部使用屬性的時候香嗓,通過'對象.不帶下滑的屬性'去使用
注意: 獲取屬性值的時候,就會自動去調用getter對應的函數(shù)
3.給屬性添加setter
屬性添加setter之前必須先添加getter
1)保證屬性名前有'_'
2)在@getter名.setter后面聲明對象方法
a.將屬性去掉下劃線作為方法名
b.需要一個self以外的參數(shù)
c.不需要返回值
- 在外部使用屬性的時候装畅,通過'對象.不帶下滑的屬性'去使用
注意: 當給屬性賦值的時候靠娱,實質是調用setter對應的方法
class Person:
count = 0
def __init__(self, name, age, gender):
self.name = name
self._age = age
self._gender = 1
self._week = 3
# 添加getter
@property
def week(self):
if self._week == 0:
return '星期天'
elif self._week == 1:
return '星期一'
elif self._week == 2:
return '星期二'
elif self._week == 3:
return '星期三'
elif self._week == 4:
return '星期四'
elif self._week == 5:
return '星期五'
elif self._week == 6:
return '星期六'
@property
def age(self):
Person.count += 1
print('年齡值被訪問!!!!')
return self._age
@age.setter
def age(self, value):
print('年齡值被修改!')
if not isinstance(value, int):
raise ValueError
if not 0 <= value <= 200:
raise ValueError
self._age = value
@property
def gender(self):
if self._gender == 1:
return '女'
return '男'
@gender.setter
def gender(self, value):
raise ValueError
p1 = Person('xiaoming', 18, '男')
# p1.age = 1908
# print(p1.age)
# print(p1.name, p1.age, p1.gender, p1.week)
print(p1.week) # 這兒實質是在調用week方法獲取返回值
p2 = Person('小花', 20, '女')
p2._week = 5
print(p2.week)
print(p1.age) # p1.age()
age1 = p1.age
print(p2.age) # p2.age()
p1.age = 67 # p1.age(200)
print(p1.gender)
# p1.gender = '男'
# 練習: 寫一個矩形類
# 有屬性: 長掠兄、寬像云、面積、周長
# 要求從生活的角度看這個矩形
class WriteError(Exception):
def __str__(self):
return '修改只讀屬性!'
class Rect:
def __init__(self, length, width):
if isinstance(length, int) or isinstance(length, float):
self._length = length
else:
raise ValueError
# self._length = 0
self._width = width
self._area = 0
self.perimeter = 0
@property
def length(self):
return self._length
@length.setter
def length(self, value):
if not (isinstance(value, int) or isinstance(value, float)):
raise ValueError
if value < 0:
raise ValueError
self._length = value
@property
def area(self):
self._area = self._length * self._width
return self._area
@area.setter
def area(self, value):
raise WriteError
r1 = Rect(100, 300)
print(r1.area)
r1.length = 20
print(r1.area)
# r1.area = 100
r2 = Rect('abc', 'ui')
1. 類中的函數(shù)
類中的方法分為: 對象方法蚂夕、類方法和靜態(tài)方法
1)對象方法
a.怎么聲明: 直接聲明
b.怎么調用: 用對象來調用
c.特點: 有指向當前對象的self
d.什么時候用:如果實現(xiàn)函數(shù)的功能需要用到對象屬性苫费,就使用對象方法
2)類方法
a.怎么聲明: 聲明在@classmethod后面
b.怎么調用: 用類來調用, '類.類方法()'
c.特點: 有自帶的參數(shù)cls,表示當前類; 這個參數(shù)在調用的時候不用傳參双抽,系統(tǒng)會自動將當前類傳給它;
cls:誰調用就指向誰(如果是對象指向的是對象對應的類)
d.什么時候用: 如果實現(xiàn)函數(shù)的功能不需要對象屬性闲礼,但是需要類的字段, 就使用類方法
3)靜態(tài)方法
a.怎么聲明: 聲明在@staticmethod后面
b.怎么調用: 通過類來調用, '類.靜態(tài)方法()'
c.特點: 沒有默認參數(shù)
d.什么時候用: 實現(xiàn)函數(shù)的功能既不需要類也不需要對象牍汹,就使用靜態(tài)方法
class Person:
num = 61
def __init__(self, name: str, age: int, gender: str):
self.name = name
self.age = age
self.gender = gender
def eat(self, food: str):
# 對象能做的事情,self都能做
print(self.name+'在吃'+food)
@classmethod
def func1(cls):
# 類能做的事情柬泽,cls都能做
print(cls)
t = cls('a', 10, 'b')
print('t:',t)
print(cls.num)
print('這是一個類方法!')
@staticmethod
def func2():
print('這是一個靜態(tài)方法!')
print(Person.num)
def func3(self):
print('這是一個函數(shù)!', self.name)
def func4(self):
print(self.age, Person.num)
Person.func1()
print(Person)
# p1 = Person('夏明', 90, '男')
# p1.func1()
Person.func2()
p1 = Person('夏明', 90, '男')
p1.func4()
class Student(Person):
num = 10
@staticmethod
def func2():
print('這是一個靜態(tài)方法!')
print(Student.num)
print('============1=============')
Student.func1()
Person.func1()
print('=============2============')
Student.func2()
Person.func2()
1.什么是繼承
繼承就是讓子類直接擁有父類的屬性和方法
子類 - 繼承者
父類/超類 - 被繼承者
2.怎么繼承
1)語法
class 類名(父類1,父類2,..):
說明文檔
類的內容
2)說明:
() - 固定寫法慎菲,如果省略相當于(object)
聲明類的時候如果沒有寫父類,默認繼承object(object又叫基類)
父類 - 一個類的父類可以有多個锨并,但是一般情況下只有一個(支持多繼承)
class Person:
num = 61
def __init__(self):
print('Person中init')
self.name = '小明'
self.age = 18
self.gender = '男'
self.__a = 10
def eat(self, food='米飯'):
print('{}在吃{}'.format(self.name, food))
@classmethod
def show(cls):
print('人類的數(shù)量:%d' % cls.num)
@staticmethod
def func1():
print('人類')
def func2(self):
print('我是'+self.name)
class Student(Person):
num = 10
def __init__(self):
# 在子類中添加對象屬性露该,需要先通過super()去調用父類的__init__來繼承父類的對象屬性
super().__init__()
print('Student中init')
self.study_id = '001'
self.class1 = 'py1904'
# 添加功能
def study(self):
print(self.name+'在好好學習!')
@staticmethod
def func1():
print('學生')
def func2(self):
print('我是學生!')
# 在子類中可以通過super()可以去調用父類的方法
# 注意: super()只能在對象方法和類方法中使用
super().func2()
stu1 = Student()
print(Student.num)
print(stu1.name, stu1.age, stu1.gender)
stu1.eat()
Student.show()
print(stu1.__dict__)
Student.func1()
stu1.func2()