python面試中較常問及的知識點梳理---高階特性

qianby發表於2021-09-11

python面試中較常問及的知識點梳理---高階特性

python的高階特性

1.函式裝飾器有什麼作用?請列舉說明?

2. Python 垃圾回收機制?

3. 魔法函式 _call_怎麼使用?

4. 如何判斷一個物件是函式還是方法?

5. @classmethod 和 @staticmethod 用法和區別

6. Python 中的介面如何實現?

7. Python 中的反射了解麼?

8. metaclass 作用?以及應用場景?

9. hasattr()、getattr()、setattr() 的用法

10. 請列舉你知道的 Python 的魔法方法及用途。

11. 如何知道一個 Python 物件的型別?

12. Python 的傳參是傳值還是傳址?

13. Python 中的元類 (metaclass) 使用舉例

14. 簡述 any() 和 all() 方法

1.函式裝飾器有什麼作用?請列舉說明?
答: 裝飾器就是一個函式,它可以在不需要做任何程式碼變動的前提下給一個函式增加額外功能,啟動裝飾的效果。 它經常用於有切面需求的場景,比如:插入日誌、效能測試、事務處理、快取、許可權校驗等場景。 下面是一個日誌功能的裝飾器

from functools import wraps
def log(label):
    def decorate(func):
       @wraps(func) 
       def _wrap(*args,**kwargs):
        try:
          func(*args,**kwargs)
          print("name",func.__name__)
        except Exception as e:
           print(e.args)
       return _wrap
    return decorate    

@log("info")
def foo(a,b,c):
     print(a+b+c)
     print("in foo")

#decorate=decorate(foo)   

if __name__ == '__main__':
    foo(1,2,3)
     #decorate()

2.Python 垃圾回收機制?

答:Python 不像 C++,Java 等語言一樣,他們可以不用事先宣告變數型別而直接對變數進行賦值。對 Python 語言來講,物件的型別和記憶體都是在執行時確定的。這也是為什麼我們稱 Python 語言為動態型別的原因。

主要體現在下面三個方法:

1.引用計數機制 2.標記-清除 3.分代回收

3.魔法函式 _call_怎麼使用?

答: call 可以把類例項當做函式呼叫。 使用示例如下

class Bar:
    def __call__(self, *args, **kwargs):
        print('in call')


if __name__ == '__main__':
    b = Bar()
    b()

4.如何判斷一個物件是函式還是方法?
答:看程式碼及結果就懂了

from types import MethodType, FunctionType

class Bar:
    def foo(self):
        pass

def foo2():
    pass

def run():
    print("foo 是函式", isinstance(Bar().foo, FunctionType))
    print("foo 是方法", isinstance(Bar().foo, MethodType))
    print("foo2 是函式", isinstance(foo2, FunctionType))
    print("foo2 是方法", isinstance(foo2, MethodType))

if __name__ == '__main__':
    run()

輸出

foo 是函式 False
foo 是方法 True
foo2 是函式 True
foo2 是方法 False

5.@classmethod 和 @staticmethod 用法和區別

答:

相同之處:@staticmethod 和@classmethod 都可以直接類名.方法名()來呼叫,不用在示例化一個類。

@classmethod 我們要寫一個只在類中執行而不在例項中執行的方法。如果我們想讓方法不在例項中執行,可以這麼做:

def iget_no_of_instance(ins_obj):
    return ins_obj.__class__.no_inst

class Kls(object):
    no_inst = 0

    def __init__(self):
        Kls.no_inst = Kls.no_inst + 1

ik1 = Kls()
ik2 = Kls()
print(iget_no_of_instance(ik1))

@staticmethod 經常有一些跟類有關係的功能但在執行時又不需要例項和類參與的情況下需要用到靜態方法:

IND = 'ON'

class Kls(object):
    def __init__(self, data):
        self.data = data

    @staticmethod
    def check_ind():
        return (IND == 'ON')

    def do_reset(self):
        if self.check_ind():
            print('Reset done for:', self.data)

    def set_db(self):
        if self.check_ind():
            self.db = 'New db connection'
        print('DB connection made for: ', self.data)

ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

6.Python 中的介面如何實現?

答:介面提取了一群類共同的函式,可以把介面當做一個函式的集合,然後讓子類去實現介面中的函式。但是在 Python 中根本就沒有一個叫做 interface 的關鍵字,如果非要去模仿介面的概念,可以使用抽象類來實現。抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被例項化。使用 abc 模組來實現抽象類。

7.Python 中的反射了解麼?

答:Python 的反射機制設定較為簡單,一共有四個關鍵函式分別是 getattr、hasattr、setattr、delattr。

8.metaclass 作用?以及應用場景?

答:metaclass 即元類,metaclass 是類似建立類的模板,所有的類都是透過他來 create 的(呼叫new),這使得你可以自由的控制建立類的那個過程,實現你所需要的功能。 我們可以使用元類建立單例模式和實現 ORM 模式。

9.hasattr()、getattr()、setattr() 的用法

答:這三個方法屬於 Python 的反射機制裡面的,hasattr 可以判斷一個物件是否含有某個屬性,getattr 可以充當 get 獲取物件屬性的作用。而 setattr 可以充當 person.name = "liming"的賦值操作。程式碼示例如下:

class Person():
    def __init__(self):
        self.name = "liming"
        self.age = 12

    def show(self):
        print(self.name)
        print(self.age)

    def set_name(self):
        setattr(Person, "sex", "男")

    def get_name(self):
        print(getattr(self, "name"))
        print(getattr(self, "age"))
        print(getattr(self, "sex"))

def run():
    if hasattr(Person, "show"):
        print("判斷 Person 類是否含有 show 方法")

    Person().set_name()
    Person().get_name()

if __name__ == '__main__':
    run()

10.請列舉你知道的 Python 的魔法方法及用途。

1 __init__:
類的初始化方法。它獲取任何傳給構造器的引數(比如我們呼叫 x = SomeClass(10, ‘foo’) , __init__就會接到引數 10 和 
‘foo’ 。 __init__在 Python 的類定義中用的最多。

2 __new__:
__new__是物件例項化時第一個呼叫的方法,它只取下 cls 引數,並把其他引數傳給 __init__ 。 __new__很少使用,但是也有它適合
的場景,尤其是當類繼承自一個像元組或者字串這樣不經常改變的型別的時候.

3 __del__:
__new__和 __init__是物件的構造器, __del__是物件的銷燬器。它並非實現了語句 del x (因此該語

11.如何知道一個 Python 物件的型別?

答:可以透過 type 方法

12.Python 的傳參是傳值還是傳址?

答:Python 中的傳參即不是傳值也不是傳地址,傳的是物件的引用。

13.Python 中的元類 (metaclass) 使用舉例

答:可以使用元類實現一個單例模式,程式碼如下:

class Singleton(type):
    def __init__(self, *args, **kwargs):
        print("in __init__")
        self.__instance = None
        super(Singleton, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        print("in __call__")
        if self.__instance is None:
            self.__instance = super(Singleton, self).__call__(*args, **kwargs)
        return self.__instance

class Foo(metaclass=Singleton):
    pass  # 在程式碼執行到這裡的時候,元類中的__new__方法和__init__方法其實已經被執行了,而不是在 Foo 例項化的時候執行。
    且僅會執行一次。

foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2)

14.簡述 any() 和 all() 方法

答: any(x):判斷 x 物件是否為空物件,如果都為空、0、false,則返回 false,如果不都為空、0、false,則返回 true。 all(x):如果 all(x) 引數 x 物件的所有元素不為 0、’’、False 或者 x 為空物件,則返回 True,否則返回 False。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3549/viewspace-2836536/,如需轉載,請註明出處,否則將追究法律責任。

相關文章