Python企業面試題3 —— 基礎篇

生而自由爱而无畏發表於2024-04-13
1. py物件導向中的繼承有什麼特點?

繼承概念的實現方式主要有2類:實現繼承、介面繼承。
實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
介面繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現的能力(子類重構爹類方法):
python兩種類:經典類 新式類
py3新式類 —— 都預設繼承 object class Animal(object): == class Animal:
py2經典類和新式類 並存
class Animal:經典類 —— 繼承順序 個別使用方法
class Animal(object): 新式類
繼承分為單繼承和多繼承
Python是支援多繼承的
如果沒有指定基類,py的類會預設繼承object類,object是所有py類的基類,它提供了一些常見的方法(如__str__)的實現。

物件可以呼叫自己本類和父類的所有方法和屬性,先呼叫自己的,自己沒有才呼叫父類的。誰(物件)呼叫方法,方法中的self就指向誰

class Foo:
    def __init__(self):
        self.func()

    def func(self):
        print('Foo.func')

class Son(Foo):
    def func(self):
        print('Son.func')

s = Son()
s.func()

# -=======================================================

class A:
    def get(self):
        self.say()
    def say(self):
        print('AAAAA')
class B(A):
    def say(self):
        print('BBBBB')

b = B()
b.get()     # BBBBB
2. 物件導向中 super 的作用?
# 用於子類繼承基類的方法
class FooParent(object):
    def __init__(self):
        self.parent = 'I\'m the parent.'
        print('Parent')
        print('1111')

    def bar(self, message):
        print("%s from Parent" % message)


class FooClild(FooParent):
    def __init__(self):
        # super(FooChild, self)首先找到FooChild 的父類(就是類FooParent),然後把類B的物件,
        # FooChild轉換為類FooParent的物件
        super(FooClild, self).__init__()
        print('Child')

    def bar(self, message):
        super(FooClild, self).bar(message)
        print('Child bar function')
        print(self.parent)

if __name__ == '__main__':
    foochild = FooClild()
    foochild.bar('HelloWorld')
3. 列舉物件導向中帶雙下劃線的特殊方法,如:__new____init__

__new__:生成例項
__init__:生成例項的屬性
__call__:例項物件加( )會執行def __call__:...... 方法裡面的內容
__del__:析構方法,當物件在記憶體中被釋放時,自動觸發執行。如當del obj或者應用程式執行完畢時,執行該方法裡面的內容
__enter____exit__:出現with語句,物件的__enter__被處罰,有返回值則賦值給as宣告的變數;with中程式碼塊執行完畢時執行 __exit__裡面的內容。
__module__:表示當前操作的物件在哪個模組 obj.__module__
__class__:表示當前操作的物件型別是什麼 obj.__class__
__doc__類的描述資訊的是,顯示print資訊無法判斷
__str__:對邊物件的字串顯示,顯示print函式 obj.__str__()
__repr__:改變物件的字串顯示,互動式解析器 obj.__repr__()
__format__:自定義格式化字串
__slots__:一個類變數,用來限制例項可以新增的屬性的數量和型別
__setitem____getitem____delitem__

class Foo:
    def __init__(self, name):
        self.name = name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):
        print('del obj[key]時,我執行')
        self.__dict__.pop(key)

    def __delattr__(self, item):
        print('del obj.key時,我執行')
        self.__dict__.pop(item)

f1 = Foo('sb')
f1['age'] = 18
f1['age1'] = 19
del f1.age1
del f1['age']
f1['name'] = 'alex'
print(f1.__dict__)

__get__():呼叫一個屬性時觸發
__set__():為一個屬性賦值時觸發
__delete__():採用del刪除屬性時觸發

4. 如何判斷是函式還是方法?
看他的呼叫者是誰,如果是類,就需要傳入一個引數self的值,這時他就是一個函式。如果呼叫者是物件,就不需要給self傳入引數值,這時他就是一個方法。
5. 靜態方法和類方法的區別?

儘管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明顯的區別。classmethod 必須有一個指向類物件的引用作為第一個引數,而staticmethod 可以沒有任何引數。

# 舉個例子:
class Num:
    # 普通方法:能夠用Num呼叫而不能用例項化物件呼叫
    def one():
        print('1')
    # 例項方法:能用例項化物件呼叫而不能用Num呼叫
    def two(self):
        print('2')
    # 靜態方法:能夠用Num和例項化物件的呼叫
    @staticmethod
    def three():
        print('3')
    # 類方法:第一個引數cls長什麼樣不重要,都是指Num類本身,呼叫時將Num類作為物件隱式的傳入方法
    @classmethod
    def go(cls):
        cls.three()

Num.one()   # 1
# Num.two()   # 報錯
Num.three()     # 3
Num.go()    # 3

i = Num()
# i.one() # TypeError: one() takes 0 positional arguments but 1 was given
i.two()     # 2
i.three()   # 3
i.go()      # 3
6. 什麼是反射?以及應用場景?

反射的核心本質就是以字串的形式去匯入個模組,利用字串的形式去執行函式。
Django中的CBV就是基於反射實現的。

7. 裝飾器的寫法以及應用場景?

含義:裝飾器本質就是函式,為其他函式新增附加功能
原則:

  • 不修改被修飾函式的程式碼
  • 不修改被修飾函式的呼叫方式
    應用場景:
  • 無參裝飾器在使用者登入、認證中常見
  • 有參裝飾器在flask的路由系統中見到過
import functools

def wrapper(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        print('我是裝飾器')
        return func
    return inner

@wrapper
def index():
    print('我是被裝飾函式')
    return None

index()

# 應用場景
- 高階函式
- 閉包
- functools.wraps(func)
8. 異常處理寫法以及如何主動丟擲異常(應用場景)
# 觸發異常
def temp_convert(var):
    try:
        return int(var)
    except ValueError as Argument:
        print("引數沒有包含數字%s" % Argument)

# 呼叫函式
temp_convert("xyz")
# 以10為基數的int()的無效文字:“xyz”

# raise 語法
class Networkerror(RuntimeError):
    def __init__(self, arg):
        self.args = arg

try:
    raise Networkerror("Bad hostname")
except Networkerror as e:
    print(e.args)
9. 什麼是物件導向的mro?

mro就是方法解析順序

10. isinstance作用以及應用場景?

isinstance(物件、類) 判斷這個物件是不是這個類或者這個類的子類的例項化

# 判斷a屬不屬於A這個類(可以判斷到祖宗類)
class A:
    pass

class B:
    pass

a = A()
b = B()
print(isinstance(b, A))     # True 判斷到祖宗類

# 任何與object都是True,內部都繼承object
print(isinstance(a, object))    # True

應用場景:
rest framework 認證的流程
scrapy-redis

11. json序列化時,預設遇到中文會轉換成Unicode,如果想要保留中文怎麼辦?

在序列化時,中文漢字總是被轉換為Unicode碼,在dumps函式中新增引數ensure_ascii=False即可解決。

12. 簡述yield和yield from關鍵字?

yield和yield from是Python中用於生成器函式的關鍵字。
(1) yield關鍵字:

  • yield用於定義一個生成器函式,生成器函式可以透過yield語句來產生一個值,並且暫停函式的執行狀態,儲存當前的上下文環境。
  • 當生成器函式被呼叫時,它會返回一個生成器物件,而不是立即執行函式體內的程式碼。
  • 每次呼叫生成器物件的__next__()方法或者使用for迴圈迭代時,生成器函式會從上次暫停的位置繼續執行,直到遇到下一個yield語句。

(2) yield from關鍵字:

  • yield from用於在生成器函式內部委託另一個可迭代物件(包括生成器)來產生值。
  • 它可以簡化生成器函式內部的迭代過程,將迭代的責任交給被委託的可迭代物件。
  • 當使用yield from委託一個可迭代物件時,生成器函式會自動處理子生成器的暫停和恢復。

相關文章