掉進懸崖的小白,總結python基礎第一階段,面向對象複習題刷起來!

掉進懸崖的小白,總結python基礎第一階段,面向對象複習題刷起來!

1.函數相關

函數的含義

廣義:
爲獲得某種東西或達到某種目的而採取的手段與行爲方式。
狹義:
函數是指由一系列的程序語句組成的代碼塊
特性:
1.帶名字的代碼段
2.函數是代碼重複使用的重要手段,是重用的基本手段:
無論現實世界還是程序世界,都以函數來達到重用的目的

函數的定義

定義語法:[]表示可選 <>表示必備
<函數名>([參數列表])<:>
待執行語句
如果有需要顯式返回<return 標識符>或

函數的參數

形式參數:由函數編寫者在預定義時限定
實際參數:任意的數據類型(爲形參賦值)在函數的調用者中定義賦值

函數的調用過程

1.調用者和被調用者相互可見,採用直接調用的方式 函數名()
2.調用者和被調用者相互不可見,先import模塊再調用:注意調用時帶上模塊.
3.特殊的調用方式,(調用類方法(類名.),調用成員方法(對象.))
析構函數等魔法函數需要用特殊的方案調用(在類內使用CTRL+o選擇調用,或者自己打def._ _ xxx_ _)

函數的返回值

返回值類型:
所有函數都需要返回
只是沒寫return的會自動返回None
函數有無返回值取決於函數的調用者是否需要返回值
注意:
函數遇到return立即退出並返回 so也常作爲控制方法結束的手段

函數的傳參規則

參數傳遞需要明白的要點:
形參的修正對實參的影響程度

參數傳遞的方式:
形式參數 = 實際參數

傳參規則:
根據形式參數類型的不同 對實際參數的影響程度也不相同
A:不可變類型:字符串、數字、布爾、元組
B:列表、類、對象、集合、字典

函數內部形參修正對函數外實參的影響程度:
A:不可變類型 不影響實際參數
B:影響實際參數(如列表,函數內部不修改整個列表時,不影響實參列表,只是修改了列表的內部)

2.註釋的使用

#、單行註釋
“”“、”“”、多行註釋(_ doc _ 訪問註釋)
‘’‘ ’‘’多行註釋(不推薦)

3.訪問控制的種類及其作用範圍

完全公開: 標識符不以_開始
保護(單下劃線前綴) :_標識符
私有(雙下劃線前綴) :__標識符
完全公開:任意位置均可訪問
保護:當前類及子類可訪問
私有:只能在當前類內訪問

4.什麼是面向對象

面向對象編程(Object Oriented Programming)簡稱OOP:
用認識一個系統的方式來分析、設計和實現一個系統
面試答案:封裝、繼承和多態即爲面向對象

5.如何抽象出類 怎麼抽象

想象這個事物有什麼(屬性),能做什麼(方法)
要求:
數據抽象(變量)—描述某類對象的狀態(對象相互區別的物理量);
代碼抽象(函數)—描述某類對象的共有的功能。

如何實現抽象:
1.分析事物,提取其狀態(變量)和行爲(函數);
2.要有主次:關注重要的,忽略不重要的

6.類怎麼定義

類(class):一種複雜的自定義數據類型
類之重要:面向對象的核心
類的定義語法:
class <類名>(父類列表):
構造方法 (製造對象模板,開闢對象地址空間)
類變量…(類內共用,可以在未創建類的對象前就用類名直接調用類屬性)
初始化方法(self,對象的變量…)(對象實例化)
類方法(1.在未產生對象的情況下即可使用類名訪問 2.對類變量進行內部封裝處理)
靜態方法(和類和對象都無關,只是一個功能,用來表達層級關係)
屬性
成員方法/對象方法
析構方法
(垃圾回收)
7.類內部都有什麼內容 各有什麼作用

8.怎麼使用類內部定義的內容 請詳細點說明

使用類的方式:和一般類型一致(聲明->賦值->使用)
如何聲明:
對象引用 = 類名(構造中需要的實參)
使用:
通過對象引用來尋找對象的變量和方法
對象引用.對象的變量
對象引用.對象方法([參數列表])
對象的構造過程
1.爲對象開闢空間,使用__new__魔術方法;
2.調用初始化方法__init__初始化;
3.返回對象的引用。

類和對象的關係:
1.類是對象的模板
2.一個類可以創建多個對象
3.對象是類一個特定的個體
4.對象有獨立的內存空間,不會互相影響

9.self的作用

self :
對象方法中必備的第一個參數
聲明:初始化及每個對象方法必須寫,且必須爲第一參數
作用:
1.初始化或對象方法被調用時,立即自動指向調用該方法的對象,無需顯式傳參(代表當前對象
2.區分同名的局部變量和對象變量

10.封裝的含義

將字段(數據成員)和行爲(代碼成員)相組合的一種機制。
目的:
1.控制對象狀態的範圍
2.加強對象自身的內聯(聯動)性
3.便於外部使用

11.怎麼實現封裝

封裝的基本要求:
特定邊界:所有的內部變化都限制在此邊界內(類內部);
特定訪問權限:在對象外部不能訪問或修改受保護的內部實現細節(_ _成員)
有外部接口(set/get方法):此對象利用它與其它對象發生關聯

使用屬性裝飾器來完成封裝:

主要用於快速構建代碼:
prop+回車:生成只讀屬性
props+回車:生成可讀寫屬性
propsd+回車:生成可讀寫刪屬性

12.繼承的含義

繼承是由已有的類創建新類的機制。
由繼承得到的類稱爲子類(派生類)
被繼承的類稱爲父類(超類)(基類)
繼承的作用:
實現軟件可重用的重要方式
增強軟件可擴充性
提高軟件的可維護性

13.派生類(子類)繼承到了父類的什麼內容?

可繼承的內容:
子類繼承父類私有以外的成員變量
:需要super().init(父級初始化參數)或使用父級統一的初始化方法
子類繼承父類私有以外的成員方法
子類繼承父類的析構方法
子類不能刪除父類的成員
子類可以覆蓋/重寫父類成員方法
子類可以增加自己獨有的成員
子類對象對父類成員的訪問權限:
子類可以訪問父類私有成員(__XXX)以外的內容

14.怎麼實現封裝

同11題
封裝時注意避免深度遞歸
函數直接或間接調用函數本身,則該函數稱爲遞歸函數

class Person:
    def __init__(self,name) -> None:
        super().__init__()
        self.name = name

    @property
    def name(self):
        return self.name  # 注意用下劃線區分,避免深度遞歸

15.super的用法

super() 用法
用super()可以實現對父類成員的訪問。
調用父類中被覆蓋的方法,如:
super().method([paramlist])
調用父類的初始化函數,如:
super().init([paramlist])

16.多繼承類的方法搜索順序(python3)

python3爲廣度優先遍歷(mro()),先搜索第一位繼承類的方法,再搜索該類的其它方法,最後搜索第二位繼承類的方法…

17.子類怎麼對繼承到的內容進行進一步重寫

子類可以覆蓋/重寫父類成員方法

18.子類對象生成時需要生成的所有對象的具體過程

欲要有子,必先有父,父類的對象屬性生成完,才能參數子類的對象屬性。

19.多態的含義

即一個名字具有多種語義。
在面向對象中指一個方法可以有多種實現版本。
類的多態表現爲方法的多態
方法的多態:覆蓋(override)。

覆蓋(重寫)要求條件:
1.父子類中
2.子類中的方法務必和父類的方法同名
3.參數個數應保持一致
4.其他的通通一樣

20.多態的好處

增強代碼可維護性
提高程序的擴展性
可以用一個參數管理具有鴨子模型的多個對象

21.如何辨識對象是否爲本類對象

判斷對象是否爲某類實例
isinstance(o,cls):辨識o是否爲cls對應類的實例或子類實例
print(isinstance(so, SubObject)) # True
print(isinstance(so, object)) # True

type(o)/o.class:按對象對應的具體類型來比對 最精確
print(type(so) is SubObject) # True
print(so.class is SubObject) # True
print(type(so) is object) # False
print(so.class is object) # False

22.如何辨識某類是否是某類的子類

issubclass(sub_cls, super_cls):辨識sub_cls是否爲super_cls子孫類
print(issubclass(SubObject, object)) # True

23.如何按內容比對對象

運算符重載
‘_ _ eq__’, ==
‘_ _ ge__’, >=
‘_ _ gt__’, >
‘_ _ le__’, <=
‘_ _ lt__’, <
‘_ _ ne__’, !=

==比較是__eq__()魔法方法的返回值
__eq__()方法未顯式在類中,若未重寫,繼承自object或自身父類
object中的__eq__()仍然比對對象的地址 so此時仍爲False
若有需求認爲對象內容相同即爲相等 需要重寫__eq__()class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass

    def __eq__(self, other):
        return self.name == other.name and self.age == other.age

此時:
print(s1 == s2)  # True

24.如何在直接輸出對象時按格式自動解析輸出

一般類中重寫將對象解析爲字符串
str’,

25.如何獲取標識符內地址

id()

26.你都知道哪些魔法方法,說說作用

信息獲取:
‘_ _ class__’, 獲取類型
‘_ _ dir__’, 獲取全描述
‘_ _ doc__’, 獲取類及類中方法的註釋
‘_ _ sizeof__’, 獲取對象字節長度 默認返回引用長度32

屬性相關:
刪除對象對象屬性時執行的方法
‘_ _ delattr__’,
獲取找不到的屬性時執行的方法
‘_ _ getattribute__’,
設置屬性時執行的方法
‘_ _ setattr__’,

運算符重載
‘_ _ eq__’, ==
‘_ _ ge__’, >=
‘_ _ gt__’, >
‘_ _ le__’, <=
‘_ _ lt__’, <
‘_ _ ne__’, !=

集合相關:
‘_ _ hash__’,

構造:
‘_ _ new__’,

初始化:
‘_ _ init__’,

對象自動解析:
交互式時使用
‘_ _ repr__’,
一般類中重寫將對象解析爲字符串
‘_ _ str__’,

格式化對象時
‘_ _ format__’,

歸約相關
‘_ _ reduce__’,
‘_ _ reduce_ex__’,

生成子類對象時:
‘_ _ init_subclass__’,

檢測子類方法
‘_ _ subclasshook__’

27.如何爲類和對象動態追加屬性

Python允許動態組裝class

class的實例屬性和類屬性甚至方法成員都可以動態添加
例:
class Student:
    pass

# 動態添加類屬性
Student.stu_count = 0
print(Student.stu_count)  # 0

# 動態添加實例屬性
s1 = Student()
s1.name = "張三"
print(s1.name)  # 張三
# 動態添加實例方法
def show():
    print("show info")
    pass
s1.info = show  # 添加實例方法
s1.info()
s2 = Student()
s2.info()  # error
# 注意:動態添加的實例屬性只能當前對象使用 若需要所有對象都能使用,請使用類名.進行動態添加(這種方式動態添加的變量是類變量,動態添加的方法要看方法的形式)

# 修改上面的代碼:
def show(self):
    print("show info")
    pass
Student.info = show  # 添加實例方法
s1.info()
s2 = Student()
s2.info()  # ok

# 刪除動態追加的內容:
對象名追加對象屬性
# del obj.a
delattr(obj,"a")

類名追加類屬性
del Foo.b

類名追加對象方法
del Foo.o_fun

28.如何限定實例可追加的屬性

限定屬性:
語法:
class limit_class:
slots = (“可動態添加的實例屬性名”, …, …)
作用:
限定對象的屬性名列表,防止隨意動態添加實例屬性

案例:
class User:
    __slots__ = ("name", "age", "tel", "address")

    def __init__(self, name, age, tel) -> None:
        self.name = name
        self.age = age
        self.tel = tel
        pass


user1 = User("admin", 19, "18866668888")
user1.address = "鄭州市經開區8888號"
print(user1.name)
# user1.money = 10000  # error 不能追加未出現在限定組內的屬性

29.類屬性及類方法的意義

類屬性:
直接在class中聲明的變量
例如:
class Student:
stu_count = 0
pass
stu_count即爲類屬性

特點:
1.可以在未創建類的對象前就用類名直接調用類屬性
2.被所有對象共用

類方法:
語法:
@classmethod
def methodname(cls):
pass
cls和self類似,只是綁定的是class自身

作用:
1.在未產生對象的情況下即可使用類名訪問
2.對類變量進行內部封裝處理

30.靜態函數的意義

函數聲明在了類的內部,無法在方法內訪問類的其他內容

語法:不能綁定self\cls
@staticmethod
def methodname():
pass

作用:
1.在未產生對象的情況下即可使用類名訪問
2.管束類的生成:構造函數__new__
3.函數集
4.多用於設計模式中

31.構造函數和初始化方法的區別

通常來說,新式類進行實例化時,new 方法會返回當前類的實例,然後調用該類的 init 方法進行實例的初始化。但是,如果 new 方法返回的不是當前類的實例,那麼,當前類的 init 方法就不會被調用。
個人理解:構造函數打造模板,開闢內存空間,初始化根據模板生成對象實例初始化。

32.單例模式步驟有哪些

from typing import Any


class Book:
    def __new__(cls, name) -> Any:
        print("類的構造開始執行 ,對象出生")
        return super().__new__(cls)

    def __init__(self, name) -> None:
        super().__init__()
        self.name = name
        print("初始化方法執行了")

    def __str__(self):
        return self.name


class BookDb:
    _instance = None
    _init_flag = False

    def __new__(cls) -> Any:
        if cls._instance is None: #判定是否開闢過地址空間
            cls._instance = super().__new__(cls) #開闢地址空間,把地址給_instance
        return cls._instance #已經開闢地址空間,給它_instance的地址

    def __init__(self) -> None:
        if not BookDb._init_flag:
            super().__init__()
            self.__books = []
            BookDb._init_flag = True # 確定只產生一個對象

    def add_book(self, book):
        self.__books.append(book)

    def show_books(self):
        for i in range(len(self.__books)):
            print(self.__books[i])


book_db = BookDb()
book_db.add_book(Book("紅與黑"))

# 若此時有另外的程序也需要書籍倉庫
book_db2 = BookDb()
book_db2.add_book(Book("編程從精通到放棄"))

# book_db.show_books()
book_db2.show_books()

33.類定義時請小心深度遞歸

封裝屬性時,注意用下劃線區分開來。

    @property
    def name(self):
        return self.name  # 注意用下劃線區分,避免深度遞歸

附加 == VS is

對於不可變類型:
==一般情況下比較value
a = 10
b = 10
# so:
a == b  # True

is比較標識符內存放的地址
id(var):可以獲取標識符內地址
只要id(x)得到的數據一致即爲True 反之爲False
a = "1"
b = "1"
print("a內地址:", id(a))
# a內地址: 2940295543976
print("b內地址:", id(b))
# b內地址: 2940295543976
print(a is b)  # True

可變類型:對象類型
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
s1 = Student("zhangsan", 17)
s2 = Student("zhangsan", 17)
is仍然比對地址及id(x)的值 所以仍然爲False
==比較是__eq__()魔法方法的返回值
__eq__()方法未顯式在類中,若未重寫,繼承自object或自身父類
object中的__eq__()仍然比對對象的地址 so此時仍爲False
若有需求認爲對象內容相同即爲相等 需要重寫__eq__()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章