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委託一個可迭代物件時,生成器函式會自動處理子生成器的暫停和恢復。