一稠氮、面向?qū)ο蟾拍?/h3>
面向?qū)ο笫且环N主流的編程思想,基本單元:對象半开,把數(shù)據(jù)和對象封裝起來隔披,實現(xiàn)很好的復用性、靈活性寂拆、擴展性奢米;
面向?qū)ο笫且环N抽象,抽象是指用分類的眼光看待事物的方法纠永,需要對事物進行總結(jié)恃慧,分析共性,利用抽象能夠簡化解決問題的難度渺蒿;
基本概念
類:定義事物的抽象特點
對象:類的一個實例
基本要素:
屬性:類的信息
方法:類的功能
類的特性
封裝:類可以實現(xiàn)很多的功能痢士,對外調(diào)用時,不需要知道具體是怎么實現(xiàn)的茂装;
繼承:定義一個新類時怠蹂,不必從頭編寫,可以從現(xiàn)有的類中繼承少态,獲得現(xiàn)有類的所有功能城侧,新類只需要編寫現(xiàn)有類缺少的功能;
多態(tài):繼承于同一個父類的不同之子類彼妻,父類的方法嫌佑,各個子類都有,但調(diào)用時的結(jié)果卻不相同侨歉;
類對象創(chuàng)建后屋摇,類命名空間中所有的命名都是有效屬性名。
二幽邓、定義類
語法:class Class_name(object):
__init__
:定義類時炮温,為類設(shè)置必要的屬性,即初始化實例
示例
class Student(object):
def __init__(self, name, sex, grade):
self.name = name,
self.sex = sex,
self.grade = grade
if __name__ == '__main__':
student = Student('larry', 'male', 5) # 創(chuàng)建實例
print('student of class:\n', student) # 查看student類
print('----------------------------')
print('type of student:\n', type(student)) # 查看student的類型
print('----------------------------')
print('attribute of student:\n', dir(student)) # 查看student的屬性
student of class:
<__main__.Student object at 0x1063207b8>
----------------------------
type of student:
<class '__main__.Student'>
----------------------------
attribute of student:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'grade', 'name', 'sex']
面向?qū)ο笫且环N主流的編程思想,基本單元:對象半开,把數(shù)據(jù)和對象封裝起來隔披,實現(xiàn)很好的復用性、靈活性寂拆、擴展性奢米;
面向?qū)ο笫且环N抽象,抽象是指用分類的眼光看待事物的方法纠永,需要對事物進行總結(jié)恃慧,分析共性,利用抽象能夠簡化解決問題的難度渺蒿;
基本概念
類:定義事物的抽象特點
對象:類的一個實例
基本要素:
屬性:類的信息
方法:類的功能
類的特性
封裝:類可以實現(xiàn)很多的功能痢士,對外調(diào)用時,不需要知道具體是怎么實現(xiàn)的茂装;
繼承:定義一個新類時怠蹂,不必從頭編寫,可以從現(xiàn)有的類中繼承少态,獲得現(xiàn)有類的所有功能城侧,新類只需要編寫現(xiàn)有類缺少的功能;
多態(tài):繼承于同一個父類的不同之子類彼妻,父類的方法嫌佑,各個子類都有,但調(diào)用時的結(jié)果卻不相同侨歉;
類對象創(chuàng)建后屋摇,類命名空間中所有的命名都是有效屬性名。
語法:class Class_name(object):
__init__
:定義類時炮温,為類設(shè)置必要的屬性,即初始化實例
示例
class Student(object):
def __init__(self, name, sex, grade):
self.name = name,
self.sex = sex,
self.grade = grade
if __name__ == '__main__':
student = Student('larry', 'male', 5) # 創(chuàng)建實例
print('student of class:\n', student) # 查看student類
print('----------------------------')
print('type of student:\n', type(student)) # 查看student的類型
print('----------------------------')
print('attribute of student:\n', dir(student)) # 查看student的屬性
student of class:
<__main__.Student object at 0x1063207b8>
----------------------------
type of student:
<class '__main__.Student'>
----------------------------
attribute of student:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'grade', 'name', 'sex']
三牵舵、定義類的屬性
- 方法
- 直接在類中定義:被類的所有對象(方法)共享柒啤,其屬性值都是一樣的倦挂;
- 通過構(gòu)造函數(shù):
def __init__(self, [, ....])
,其屬性值依賴于傳入的值担巩;
- 訪問控制
實際上方援,Python中并沒有訪問控制,Python沒有提供私有屬性的功能涛癌;
通過屬性命名規(guī)范可以實現(xiàn)訪問控制肯骇,不希望被外部訪問的屬性,在屬性名前添加雙下劃線
(__)
即可祖很。在實際工作中笛丙,這些命名規(guī)范全靠自覺;單下劃線開頭的屬性假颇,可以在子類中使用胚鸯;雙下劃線開頭的屬性,不能被外部調(diào)用笨鸡,也不能在子類中使用姜钳,即繼承時這些私有屬性和方法不會被覆蓋。
- 示例
class Person(object):
hobby = 'Play Computer' # 直接在類中定義屬性hobby
def __init__(self, name, sex, age): # 構(gòu)造函數(shù)中定義初始化屬性
self.name = name,
self._sex = sex,
self.__age = age
def get_age(self):
return self.__age
if __name__ == '__main__':
person = Person('larry', 'female', '28') # 創(chuàng)建實例
print('attribute of person:\n', dir(person)) # 查看類的屬性
print(person.__dict__) # 查看構(gòu)造函數(shù)中定義的屬性
print(person.get_age()) # 調(diào)用獲取age屬性的方法
print(person._Person__age) # 變相獲取雙下劃線開頭的age屬性
attribute of person:
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_sex', 'get_age', 'hobby', 'name']
{'name': ('larry',), '_sex': ('female',), '_Person__age': '28'}
28
28
四形耗、定義類的方法
- 概念
函數(shù)是直接使用函數(shù)名進行調(diào)用哥桥;
方法是類的一部分,必須和對象結(jié)合在一起使用激涤,使用類名進行調(diào)用拟糕,而不是某個對象;
方法的訪問限制倦踢,和屬性一樣送滞,沒有嚴格的語法控制,只是遵循一些規(guī)范辱挥;
類中定義的方法犁嗅,都是實例方法,可以看作是類的一個屬性晤碘,第一個參數(shù)永遠是self褂微,表示創(chuàng)建的實例本身,
@classmethod:裝飾的方法是類方法园爷,類方法的第一個參數(shù)將傳入類本身宠蚂,通常將參數(shù)名命名為cls;
@property:裝飾的方法腮介,調(diào)用時肥矢,像訪問屬性一樣(不需要帶括號)。
- 示例
class Person(object):
hobby = 'Play Cumputer' # 直接在類中定義屬性hobby
def __init__(self, name, sex, age): # 構(gòu)造函數(shù)中定義初始化屬性
self.name = name,
self._sex = sex,
self.__age = age
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_age(self):
return self.__age
def self_introduction(self):
print(f"My name is {self.name[0]}\nI am {self.__age} years old")
if __name__ == '__main__':
person = Person('larry', 'male', 28)
print(dir(person))
print(Person.get_hobby())
print(person.get_age)
person.self_introduction()
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_sex',
'get_age', 'get_hobby', 'hobby', 'name', 'self_introduction']
Play Cumputer
28
My name is larry
I am 28 years old
五叠洗、類的繼承
- 概念
- 繼承的子類:會繼承父類的屬性和方法甘改,也可以自己定義,覆蓋父類的屬性和方法灭抑;
- 使用supper()調(diào)用父類的方法十艾,或者直接使用父類的名稱調(diào)用;
- isinstance():可以判斷一個實例是否是指定的類腾节;
- issubclass():判斷一個類是否是子類;
- 類繼承機制允許多重繼承忘嫉,派生類可以覆蓋(override)基類中的任何方法或類,可以使用相同的方法名稱調(diào)用基類的方法案腺。
- 示例
# 類的繼承
class Person(object):
hobby = 'Play Cumputer' # 直接在類中定義屬性hobby
def __init__(self, name, sex, age): # 構(gòu)造函數(shù)中定義初始化屬性
self.name = name,
self._sex = sex,
self.__age = age
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_age(self):
return self.__age
def self_introduction(self):
print(f"My name is {self.name[0]}\n I am {self.__age} years old")
class Student(Person):
def __init__(self, name, sex, age, weight):
super(Student, self).__init__(name, sex, age)
self.weight = weight
if __name__ == '__main__':
student = Student('larry', 'male', 28, 62)
print(type(student))
print(dir(student))
print(student.__dict__)
print(isinstance(student, Student)) # 實例student庆冕,是否是指定的類Student
print(issubclass(Student, Person)) # 類Student,是否是類Person的子類
<class '__main__.Student'>
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_sex',
'get_age', 'get_hobby', 'hobby', 'name', 'self_introduction', 'weight']
{'name': ('larry',), '_sex': ('male',), '_Person__age': 28, 'weight': 62}
True
True
六劈榨、多態(tài)
- 概念
- 有了繼承访递,才有了多態(tài),在調(diào)用類實例方法時同辣,盡量把變量當作父類拷姿,以便所有子類類型都可以正常接收;
- 多態(tài):繼承于同一個父類的不同之子類旱函,父類的方法响巢,各個子類都有,但調(diào)用時的結(jié)果卻不相同棒妨。
- 示例
# 類的多態(tài)
class Person(object):
hobby = 'Play Cumputer' # 直接在類中定義屬性hobby
def __init__(self, name, sex, age): # 構(gòu)造函數(shù)中定義初始化屬性
self.name = name,
self._sex = sex,
self.__age = age
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_age(self):
return self.__age
def self_introduction(self):
return f"My name is {self.name[0]}\nI am {self.__age} years old"
class Student(Person):
def __init__(self, name, sex, age, weight):
super(Student, self).__init__(name, sex, age)
self.weight = weight
def self_introduction(self):
return f"My name is {self.name[0]}\n My weight is {self.weight}"
def introduce(class_name):
if isinstance(class_name, Person):
return class_name.self_introduction()
if __name__ == '__main__':
person = Person('larry', 'male', 28)
student = Student('larry', 'male', 28, 62)
print(introduce(person))
print(introduce(student))
My name is larry
I am 28 years old
My name is larry
My weight is 62
七踪古、類的魔術(shù)方法
- 概念
- 絕大多數(shù)的Python內(nèi)置函數(shù),都有對應(yīng)的魔術(shù)方法券腔,可以在類中使用灾炭;
- 魔術(shù)方法,可以更方便自由地進行定制類颅眶,包括:對象建立蜈出、屬性訪問、運算符的支持涛酗、特殊語法等铡原;
- 面向?qū)ο笾校Q前后各有2個下劃線
(__)
的方法商叹,都是魔術(shù)方法燕刻,是定義在類中的,不需要直接調(diào)用剖笙; - 類中常用的魔術(shù)方法
魔術(shù)方法 | 含義 |
---|---|
__init__() | 構(gòu)造函數(shù)卵洗,創(chuàng)建實例的時候被調(diào)用 |
__str__() | 返回適合人看的字符,print()調(diào)用的就是該方法 |
__repr__ | 返回適合機器看的字符 |
__eq__ | 判斷是否相等,比較運算符 |
__add__ | 相加过蹂,數(shù)字運算符 |
__and__ | 判斷條件十绑,邏輯運算符 |
__dir__ | 查看對象的屬性 |
__setattr__ | 設(shè)置對象的屬性,注意避免循環(huán)遞歸酷勺,導致死循環(huán) |
__getattribute__ | 訪問對象的屬性本橙,注意避免死循環(huán) |
__len__ | 獲取對象參數(shù)個數(shù) |
__call__ | 調(diào)用對象 |
- 示例
# 類中的魔術(shù)方法
class Person(object):
def __init__(self, name, age):
"""
構(gòu)造函數(shù),初始化定義屬性
"""
self.name = name,
if isinstance(age, int): # 確保age屬性必須是數(shù)值
self.age = age
else:
raise Exception ('age must be int')
def __eq__(self, other):
"""
判斷2個對象是否相等
"""
if isinstance(other, Person): # 確保2個對象是同一個父類
if self.age == other.age:
return True
else:
return False
else:
raise Exception ('The class of object must be Person')
def __add__(self, other):
"""
2個對象相加
"""
if isinstance(other, Person): # 確保2個對象是同一個父類
return self.age + other.age
else:
raise Exception ('The class of object must be Person')
def __str__(self):
"""
輸出指定內(nèi)容
"""
return f"{self.name[0]} is {self.age} years old"
def __dir__(self):
"""
設(shè)置輸出的屬性
"""
return self.__dict__.keys()
def __setattr__(self, name, value):
"""
設(shè)置對象的屬性
"""
self.__dict__[name] = value
def __getattribute__(self, name):
"""
訪問對象的屬性
"""
return super(Person, self).__getattribute__(name)
def __len__(self):
"""
返回類的參數(shù)個數(shù)
"""
return len(self.name)
def __call__(self, friend): # friend是調(diào)用對象時傳入的參數(shù)
"""
調(diào)用對象
"""
return f"My name is {self.name[0]} ... My friend is {friend}"
if __name__ == '__main__':
p1 = Person('Larry', 28)
p2 = Person('Python', 30)
print(p1 == p2) # __eq__根據(jù)age屬性脆诉,判斷是否相等
print(p1 + p2) # __add__對age屬性甚亭,相加
print(p1) # __str__返回指定的內(nèi)容
print(dir(p1)) # __dir__輸出指定的屬性
print(p1.age) # __setattar__設(shè)置對象的屬性
print(len(p1)) # __len__返回類的參數(shù)個數(shù)
print(p1('Tom')) # __call__調(diào)用對象
False
58
Larry is 28 years old
['age', 'name']
28
1
My name is Larry ... My friend is Tom