類中的方法分為:對(duì)象方法, 類方法和靜態(tài)方法
1.對(duì)象方法
a.直接聲明在類中
b.有默認(rèn)參數(shù)self
c.通過對(duì)象去調(diào)用: 對(duì)象.對(duì)象方法()
2.類方法
a.在聲明前添加@classmethod
b.有默認(rèn)參數(shù)cls, 調(diào)用的時(shí)候不需要給cls傳參改执。系統(tǒng)會(huì)自動(dòng)將調(diào)用當(dāng)前類方法的類傳給cls熟尉。
cls最終指向的是一個(gè)類累铅,類可以做的事情cls都可以做
c.通過類去調(diào)用: 類.類方法()
3.靜態(tài)方法
a.在聲明前添加@staticmethod
b.沒有默認(rèn)參數(shù)
c.通過類去調(diào)用:類.類方法()
4.對(duì)象方法苦银、類方法和靜態(tài)的方法的選擇
a.什么時(shí)候使用對(duì)象方法:
當(dāng)實(shí)現(xiàn)函數(shù)的功能需要用到對(duì)象的屬性的時(shí)候就使用對(duì)象方法
b.什么時(shí)候使用類方法:
實(shí)現(xiàn)函數(shù)的功能不需要對(duì)象的屬性跷叉,但是需要類的時(shí)候就使用類方法
c.什么時(shí)候使用靜態(tài)方法
實(shí)現(xiàn)函數(shù)的功能既不需要對(duì)象的屬性俗扇,也不需要類的時(shí)候驶社,就使用靜態(tài)方法
class Person():
# 類的字段
num = 61
def __init__(self, name):
self.name = name
# 對(duì)象方法
def eat(self, food):
# print(Person.num)
print('%s在吃%s' % (self.name, food))
# 類方法
@classmethod
def destroy(cls):
# cls = Person
print('cls:',cls)
print('人類破壞環(huán)境')
# 可以用cls來創(chuàng)建對(duì)象
p1 = cls('小明')
p1.eat('面包')
# 可以用cls使用類的字段
print(cls.num)
# 可以用cls調(diào)用類相關(guān)的方法
# 靜態(tài)方法
@staticmethod
def hit_animal():
print('人類毆打小動(dòng)物!')
print(Person.num)
print('Person:', Person)
Person.destroy()
Person.hit_animal()
數(shù)學(xué)類,屬性:pi 功能:求兩個(gè)數(shù)的和, 求一個(gè)圓的面積
class Math:
pi = 3.1415926
@staticmethod
def sum(num1, num2):
return num1+num2
@classmethod
def circle_area(cls, r):
return cls.pi * (r ** 2)
1.私有化
在類中炸站,可以通過在屬性名前,或者方法名前加(注意:不能以結(jié)尾),那么這個(gè)屬性或者方法就會(huì)變成私有的疚顷。
私有的屬性和方法在類的外部不能使用
class Person:
__num = 100 # 私有的屬性
__number__ = 200 # 不是私有屬性
def __init__(self):
self.name = '張三'
self.__age = 18
def __show_message(self):
print(Person.__num)
print('名字:', self.name, '年齡:', self.__age)
def func1(self):
self.__show_message()
2.私有化原理
python中沒有真正的私有化, 不能從訪問權(quán)限上控制屬性和方法的使用旱易。
只是在名字前有但是沒有以結(jié)尾的名字前再加了'_類名',
導(dǎo)致不能直接通過原屬性和方法名進(jìn)行訪問
class Dog:
def __init__(self, name, color):
self.__name = name
self.__color = color
dog1 = Dog('大黃', '黃色')
print(dog1.__dict__)
# print(dog1.__name, dog1.__color)
print(dog1._Dog__name)
1.getter和setter
如果希望在獲取對(duì)象屬性之前要做點(diǎn)兒別的事情,就給這個(gè)屬性添加getter腿堤;
如果希望在給對(duì)象屬性賦值之前做點(diǎn)兒別的事情阀坏,就給這個(gè)屬性添加setter
2.給對(duì)象屬性添加getter
a.屬性命名的時(shí)候,屬性名前加_; 例如:self._age = 0
b.聲明一個(gè)函數(shù)笆檀,函數(shù)的名字是屬性名(不要下劃線),不需要額外參數(shù),有返回值忌堂;并且函數(shù)前使用@property修飾。
這個(gè)函數(shù)的返回值就是獲取屬性的結(jié)果
例如:
@property
def age(self):
return 年齡相關(guān)值
c.當(dāng)需要獲取屬性的時(shí)候通過對(duì)象.不帶下劃線的屬性酗洒;例如:對(duì)象.age
3.給對(duì)象屬性添加setter
想要給對(duì)象屬性添加setter士修,必須先給它添加getter
a.屬性命名的時(shí)候,屬性名前加_; 例如:self._age = 0
b.聲明一個(gè)函數(shù)樱衷,函數(shù)的名字是屬性名(不要下劃線)棋嘲,需要一個(gè)額外的參數(shù),不用返回值;
并且函數(shù)前使用@getter名.setter修飾
例如:
@age.setter
def age(self, value):
self._age = value
c.當(dāng)需要給屬性賦值的時(shí)候,通過對(duì)象.不帶下劃線的屬性來賦值矩桂;例如: 對(duì)象.age = 100
class Person:
def __init__(self, name='小紅'):
self.name = name
self._age = 60
self.sex = '男'
# 這兒的age函數(shù)就是屬性_age的getter方法
@property
def age(self):
if self._age < 1:
return '嬰兒'
elif self._age < 18:
return '未成年'
elif self._age < 50:
return '中年'
else:
return '老年'
補(bǔ)充:打印自己聲明的類的對(duì)象的時(shí)候沸移,默認(rèn)打印的是:<模塊名.類名 object at 對(duì)象地址>
如果不希望以默認(rèn)的方式去打印對(duì)象,可以實(shí)現(xiàn)repr魔法方法耍鬓。打印對(duì)象的時(shí)候就會(huì)打印這個(gè)方法的返回值
這個(gè)函數(shù)的返回值必須是字符串
1.繼承
python中的類支持繼承阔籽,并且支持多繼承。
python中默認(rèn)情況是繼承自object(object是python中所有類的基類)
a.什么是繼承
一個(gè)類可以繼承另外一個(gè)類牲蜀,繼承者我們叫子類笆制,被繼承者叫父類。繼承就是讓子類直接擁有父類中的內(nèi)容
b.可以繼承哪些內(nèi)容
所有的屬性和方法都可以繼承
class Person(object):
num = 61
# 注意:__slots__對(duì)應(yīng)的值不會(huì)被繼承
__slots__ = ('name', 'age', 'sex')
def __init__(self):
self.name = '張三'
self.age = 0
self.sex = '男'
def show_message(self):
print('%s你好嗎?' % self.name)
子類除了擁有從父類繼承下來的屬性和方法涣达,還擁有屬于自己的屬性和方法
1.在子類中添加方法
a.添加一個(gè)新的方法
直接在子類中聲明其他的方法;
添加后子類可以調(diào)用自己的方法也可以調(diào)用父類的方法在辆,但是父類不能調(diào)用子類的方法
b.重寫父類的方法: 重新實(shí)現(xiàn)父類的方法
完全重寫 - 覆蓋父類的功能 - 直接在子類中重新實(shí)現(xiàn)父類的方法
部分重寫 - 保留父類的功能,添加新的功能 - 在子類中實(shí)現(xiàn)父類方法的時(shí)候通過super()去調(diào)用父類的方法度苔,
再添加新的功能
注意:a.可以子類的方法中通過super()去調(diào)用父類的方法
super(類, 對(duì)象) - 獲取對(duì)象中父類的部分(要求對(duì)象是這個(gè)指定的類的對(duì)象)
b.靜態(tài)方法中不能使用super()
c.類中方法的調(diào)用過程
通過對(duì)象或者類調(diào)用方法的時(shí)候匆篓,先看當(dāng)前類中是否聲明過這個(gè)方法,如果聲明過就直接調(diào)用當(dāng)前類對(duì)應(yīng)的方法;
如果當(dāng)前類中沒有聲明過寇窑,會(huì)去找父類中有沒有聲明過這個(gè)方法鸦概,聲明過就調(diào)用父類的方法;
如果父類中也沒有聲明過,就去找父類的父類...以此類推甩骏,直到object中也沒有聲明過窗市,程序才會(huì)崩潰
class Person:
# 類的字段
num = 61
#對(duì)象屬性
def __init__(self):
self.name = '張三'
self.age = 0
self.sex = '男'
def fun1(self):
print('Person的對(duì)象方法')
方法
def show_message(self):
print('%s,你好嗎先慷?' % self.name)
@staticmethod
def info():
print('我是人類')
class Student(Person):
def study(self):
print('%s在學(xué)生' % self.name)
@classmethod
def message(cls):
super().info()
print('我是學(xué)生!')
完全重寫
@staticmethod
def info():
print('我是學(xué)生!W刹臁论熙!')
保留父類的功能
def show_message(self):
super().show_message()
print('我去上學(xué)~')
super().fun1()
1.添加類的字段
直接在子類中添加新的字段
2.添加對(duì)象屬性
繼承對(duì)象屬性是通過繼承父類的init方法繼承下來的
如果想要在保留父類繼承下來的對(duì)象屬性的前提下,添加新的對(duì)象屬性摄狱,
需要在子類的init方法中脓诡,通過super()去調(diào)用父類的init方法
class Person:
num = 61
def __init__(self, name):
self.name = name
self.age = 0
class Student(Person):
number = 100
def __init__(self, name):
super().__init__(name)
self.study_id = '001'
print(Student.number, Student.num)
stu1 = Student('小明')
print(stu1.name, stu1.age, stu1.study_id)
練習(xí):
聲明一個(gè)動(dòng)物類,有屬性:年齡媒役,顏色祝谚,類型。
要求創(chuàng)建動(dòng)物對(duì)象的時(shí)候類型和顏色必須賦值刊愚,年齡可以賦值也可以不賦值
聲明一個(gè)貓類踊跟,有屬性:年齡,顏色鸥诽,類型, 愛好
要求創(chuàng)建貓對(duì)象的時(shí)候商玫,顏色必須賦值,年齡和愛好可以賦值也可以不賦值牡借,類型不能賦值
class Aniaml:
def __init__(self, type, color, age=0):
self.type = type
self.color = color
self.age = age
class Cat(Aniaml):
def __init__(self, color, age=0, hobby=''):
super().__init__('貓科', color, age)
self.hobby = hobby
an1 = Aniaml('犬科', '黃色')
an2 = Aniaml('犬科', '黃色', 10)
cat1 = Cat('白色')
cat2 = Cat('灰色', 3)
cat3 = Cat('灰色', hobby='睡覺')
cat4 = Cat('灰色', 3, '睡覺')