def Stack(object):
def __init__(self):
self.stack = []
def push(self,value):
# 進棧
self.stack.append(value)
def pop(self):
# 出棧
if self.stack:
self.stack.pop()
else:
raise LookupError('stack is empty!')
def is_empty(self):
# 查看stack是否為空
reture bool(self.stack)
def top(self):
# 取出stack中最新的值
return self.stack[-1]
50、常用字符串格式化哪幾種?
1、%s %d
2、format格式化輸出
3、print(f'內容{變量名}')
51、簡述 生成器、迭代器、可迭代對象 以及應用場景?
生成器:在 Python 中,一邊循環一邊計算的機制,稱為 生成器(generator),
通過next()取值,兩種表現形式1、將列表生成式的[]改為()2、含有yield關鍵字的函數
應用場景:優化代碼,節省內存
迭代器:是訪問集合元素的一種方式。迭代器同時實現了__iter__和__next__方法
可迭代對象:只要實現了__iter__方法的對象就是可迭代對象
52、用Python實現一個二分查找的函數。
lis = [0, 1, 3, 4, 5, 6, 7, 9, 10, 11,12,16,17]
def binary_search(li, val):
low = 0
high = len(li)-1
while low <= high:
mid = (low + high) // 2
if li[mid] < val:
low = mid + 1
elif li[mid] > val:
high = mid - 1
else:
return mid
return None
53、談談你對閉包的理解?
在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用。這樣就構成了一個閉包。
一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。
但是閉包是一種特殊情況,如果外函數在結束的時候發現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給了內部函數,然后自己再結束。
54、os和sys模塊的作用?
os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的接口;
sys模塊負責程序與python解釋器的交互,提供了一系列的函數和變量,用于操控python的運行時環境。
55、如何生成一個隨機數?
import random
def rdm(n):
lis= []
for i in range(n):
n= random.randint(1,9)
lis.append(str(n))
s = ''.join(lis)
return int(s)
56、如何使用python刪除一個文件?
import os
os.remove(r'path')
57、談談你對面向對象的理解?
面向對象的程序設計的核心是對象(上帝式思維),要理解對象為何物,必須把自己當成上帝,上帝眼里世間存在的萬物皆為對象,
不存在的也可以創造出來。對象是特征和技能的結合,其中特征和技能分別對應對象的數據屬性和方法屬性。
優點是:解決了程序的擴展性。對某一個對象單獨修改,會立刻反映到整個體系中,如對游戲中一個人物參數的特征和技能修改都很容易。
缺點:可控性差,無法向面向過程的程序設計流水線式的可以很精準的預測問題的處理流程與結果,
面向對象的程序一旦開始就由對象之間的交互解決問題,即便是上帝也無法預測最終結果。
應用場景:需求經常變化的軟件,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟件,游戲等都是面向對象的程序設計大顯身手的好地
58、Python面向對象中的繼承有什么特點?
1:在繼承中基類的構造(__init__()方法)不會被自動調用,它需要在其派生類的構造中親自專門調用。
2:在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。
區別于在類中調用普通函數時并不需要帶上self參數
3:Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,它才開始到基類中逐個查找。
(先在本類中查找調用的方法,找不到才去基類中找)。
59、面向對象深度優先和廣度優先是什么?
Python的類可以繼承多個類,那么其尋找類方法的方式有兩種:
當類是經典類時(主要在python2版本中的沒有主動繼承object的類),多繼承情況下,會按照深度優先方式查找
當類是新式類時(python3版本中的所有類和python2中主動繼承object的類),多繼承情況下,會按照廣度優先方式查找
簡單點說就是:經典類是縱向查找,新式類是橫向查找
60、面向對象中super的作用?
1、super在面向對象繼承類中代指父類,書寫方法super(類名,self).屬性或者方法或super().屬性或者方法
2、super方法可以增加類之間調用的靈活性,當父類名發生變化時不必修改
3、super方法在類的多繼承時可以簡化代碼,避免代碼冗余
4、super機制里可以保證公共父類僅被執行一次,執行的順序遵循MRO,廣度優先查詢方法
61、是否使用過functools中的函數?其作用是什么?
functools用于高階函數:指那些作用于函數或者返回其他函數的函數。通常情況下,只要是
可以被當做函數調用的對象就是這個模塊的目標。
62、列舉面向對象中帶雙下劃線的特殊方法,如:new、init
__new__:構造方法,創建一個對象,實例化時第一個被執行,返回一個創建好的對象及__init__(self)的self,
只有繼承了object的類才會有這個方法
__init__:初始化方法,__init__在__new__的基礎上完成一些其它初始化的動作,__init__沒有返回值
63、如何判斷是函數還是方法?
函數和方法都封裝了一些獨立的功能,如果在類中定義的函數那就是方法(對象或者類名點方法名調用),否則就是函數(函數名()直接調用)
64、靜態方法和類方法區別?
靜態方法:是既不是用類中的屬性又不使用對象中的屬性,由類或者對象調用的方法,依賴python裝飾器@staticmethod來實現
類方法:只使用類中的靜態變量,一般都是由類調用,依賴python裝飾器@classmethod來實現
65、列舉面向對象中的特殊成員以及應用場景?
__call__:對象的構造方法,對象加上(),可以觸發這個類的__call__方法。
__len__:內置函數的len函數是依賴類中的__len__方法
__eq__:判斷值是否相等的時候依賴__eq__方法
__hash__:判斷hash值是否相等的時候依賴__hash__方法(拓展:set的去重機制其實就是根據__hash__和__eq__方法實現的)
__str__:和str() print() %s 都是息息相關的,返回值一定是字符串類型
__repr__:和 repr() %r都是息息相關的,在沒有__str__方法時,__repr__可以完全取代__str__。
__del__ 析構方法,對應著一個對象的刪除之前執行的內容
66、1、2、3、4、5 能組成多少個互不相同且無重復的三位數
count = 0
for i in range(1,6):
for j in range(1,6):
for k in range(1,6):
if (i != j) and (i != k) and (j != k):
count += 1
if count % 6:
print(f'{i}{j}{k}', end='|')
else:
print(f'{i}{j}{k}')
print(count)
67、什么是反射?以及應用場景?
定義:通過用字符串數據類型的變量名來訪問這個變量的值,在python面向對象中的反射,通過字符串的形式操作對象相關的屬性或方法.
應用場景:用于處理通過用戶輸入,文件讀取,或者網絡傳輸所得到的字符串形式的指令來完成對應的操作
68、metaclass作用?以及應用場景?
metaclass,直譯為元類,簡單的解釋就是:當我們定義了類以后,就可以根據這個類創建出實例,
所以:先定義類,然后創建實例。但是如果我們想創建出類呢?那就必須根據metaclass創建出類,
所以:先定義metaclass,然后創建類。換句話說,你可以把類看成是metaclass創建出來的“實例”
69、用盡量多的方法實現單例模式。
1、基于__new__()方法
class Person:
def __new__(cls, *args, **kwargs):
if not hasattr(cls,cls._instance):
# cls._instance = object.__new__(cls)
cls._instance = super().__new__(cls)
return cls._instance
2、基于模塊導入方式,現在一個py文件中寫好一個類,實例化一個對象。以后用這個類直接導入這個模塊就是單例模式。
3、基于裝飾器方法實現
def singleton(cls, *args, **kwargs):
instance_dic = {}
def inner(*args, **kwargs):
if cls not in instance_dic:
instance_dic['cls'] = cls(*args, **kwargs)
return instance_dic['cls']
return inner
@singleton
class Person:
pass
70、裝飾器的寫法以及應用場景。
裝飾器的寫法:
def wrapper(func):
def inner(*args,**kwargs):
'被裝飾之前的操作'
ret = func(*args,**kwargs)
'被裝飾之后的操作'
return ret
return inner
裝飾器的應用場景:
比如注冊登錄、插入日志,性能測試,事務處理,緩存等等場景
71、異常處理寫法以及如何主動跑出異常(應用場景)
異常處理的常規寫法:
try:
執行的主體函數
except Exception as e:
print(str(e))
主動拋出異常:
raise TypeError('出現了不可思議的異常')#TypeError可以是任意的錯誤類
72、什么是面向對象的mro
MRO(Method Resolution Order 方法解析順序)是面向對象中用于查詢類的多繼承的繼承順序的方法,它是基于算法來實現的,不同的算法實現的MRO的順序不同
73、isinstance作用以及應用場景?
isinstance作用是來判斷一個對象是否是一個已知的類型
74、寫代碼并實現:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
代碼實現
def func(li,target):
try:
for i in range(0,len(li)):
num = target-li[i]
if num in li:
return [i,li.index(num)]
except:print('li類型為數組類型,內的元素需是整型,target也為整型,請檢查')
else:return None
75、json序列化時,可以處理的數據類型有哪些?如何定制支持datetime類型?
1、可以處理的數據類型是 string、int、list、tuple、dict、bool、null
2、定制支持datetime類型
--------------------------官方文檔的memo-----------------------------------------------
>>>import json
>>>class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... return json.JSONEncoder.default(self, obj)
...
>>>dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>>ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>>list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']
----------------------------------------------------------------------------------------
import json
import datetime
ret = datetime.datetime.now()
class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.date):
return obj.strftime('%Y-%m-%d %H:%M:%S')
else:
return json.JSONEncoder.default(self, obj)
print(json.dumps(ret,cls=CJsonEncoder))
76、json序列化時,默認遇到中文會轉換成unicode,如果想要保留中文怎么辦?
在序列化是將json.dumps中的默認參數ensure_ascii改為False就可以保留中文了
json.dumps(obj,ensure_ascii=False)
77、什么是斷言?應用場景?
assert 條件,'自定義錯誤提示(可有可無)' 例:assert 1 == 0,'這是一個低級的錯誤'
合約式設計是斷言的經典應用,在一個正確的程序里,所有的前置條件和后置條件都將得到處理。
78、使用代碼實現查看列舉目錄下的所有文件。
方法一:遞歸處理
import os
url = r'C:\Users\Mr.Wang\PycharmProjects\untitled\前段學習'
def check_file(url,li = []):
if os.path.isdir(url):
file_list = os.listdir(url)
for ret in file_list:
base_url = os.path.join(url,ret)
if os.path.isfile(base_url):
li.append(ret)
else: check_file(base_url)
return li
else:return os.path.basename(url)
方法二:堆棧的思想處理
import os
url = r'C:\Users\Mr.Wang\PycharmProjects\untitled\python基礎'
lis = [url]
while lis:
url = lis.pop()
ret_list = os.listdir(url)
for name in ret_list:
abs_path = os.path.join(url,name)
if os.path.isdir(abs_path):
lis.append(abs_path)
else:print(name)
79、簡述 yield和yield from關鍵字。
yield 是一個類似 return 的關鍵字,只是這個函數返回的是個生成器當你調用這個函數的時候,
函數內部的代碼并不立馬執行 ,這個函數只是返回一個生成器對象,當你使用for進行迭代的時候,
函數中的代碼才會執行
yield from 的主要功能是打開雙向通道,把最外層的調用方與最內層的子生成器連接起來,
這樣二者可以直接發送和產出值,還可以直接傳入異常,而不用在位于中間的協程中添加大量處理異常的樣板代碼。
有了這個結構,協程可以通過以前不可能的方式委托職責。
更多解析詳見:http://blog.gusibi.com/post/python-coroutine-yield-from/
80、代碼實現六位隨機驗證碼
import random
s = ''
for i in range(6):
num = random.randint(0,9)
alpha1 = chr(random.randint(65,90))
alpha2 = chr(random.randint(97,122))
ret = random.choice([num,alpha1,alpha2])
s += str(ret)
print(s)
81、代碼實現隨機發紅包功能
import random
def red_packge(money,num):
li = random.sample(range(1,money*100),num-1)
li.extend([0,money*100])
li.sort()
return [(li[index+1]-li[index])/100 for index in range(num)]
ret = red_packge(100,10)
print(ret)
--------------------------生成器版-------------------------------------------
import random
def red_packge(money,num):
li = random.sample(range(1,money100),num-1)
li.extend([0,money100])
li.sort()
for index in range(num):
yield (li[index+1]-li[index])/100
ret = red_packge(100,10)
print(ret)
補充
1、請盡可能列舉python列表的成員方法,并給出列表操作的答案:
(1) a=[1, 2, 3, 4, 5], a[::2]=? a[-2:]=?
a[::2]=[1,3,5],
a[-2:] = [4,5]
(2)一行代碼實現對列表a中的偶數位置的元素進行加3后求和?
sum([i+3 for i in a[::2]])
(3)將列表a的元素順序打亂,再對a進行排序得到列表b,然后把a和b按元素順序構造一個字典d。
import random
random.shuffle(a)
b=a.sort()
d={}
for i in range(len(a)):d[a[i]] = b[i]
2、 Python自省
自省就是面向對象的語言所寫的程序在運行時,就能知道對象的類型。也就是程序運行時能夠獲得對象的類型。比如type(),dir(),getattr(),hasattr(),isinstance()。
3、Python是如何進行內存管理的?
從三個方面來說,一對象的引用計數機制,二垃圾回收機制,三內存池機制
一、對象的引用計數機制
Python內部使用引用計數,來保持追蹤內存中的對象,所有對象都有引用計數。
引用計數增加的情況:
1,一個對象分配一個新名稱
2,將其放入一個容器中(如列表、元組或字典)
引用計數減少的情況:
1,使用del語句對對象別名顯示的銷毀
2,引用超出作用域或被重新賦值
sys.getrefcount( )函數可以獲得對象的當前引用計數
多數情況下,引用計數比你猜測得要大得多。對于不可變數據(如數字和字符串),解釋器會在程序的不同部分共享內存,以便節約內存。
二、垃圾回收
1,當一個對象的引用計數歸零時,它將被垃圾收集機制處理掉。
2,當兩個對象a和b相互引用時,del語句可以減少a和b的引用計數,并銷毀用于引用底層對象的名稱。然而由于每個對象都包含一個對其他對象的應用,因此引用計數不會歸零,對象也不會銷毀。(從而導致內存泄露)。為解決這一問題,解釋器會定期執行一個循環檢測器,搜索不可訪問對象的循環并刪除它們。
三、內存池機制
Python提供了對內存的垃圾收集機制,但是它將不用的內存放到內存池而不是返回給操作系統。
1,Pymalloc機制。為了加速Python的執行效率,Python引入了一個內存池機制,用于管理對小塊內存的申請和釋放。
2,Python中所有小于256個字節的對象都使用pymalloc實現的分配器,而大的對象則使用系統的malloc。
3,對于Python對象,如整數,浮點數和List,都有其獨立的私有內存池,對象間不共享他們的內存池。也就是說如果你分配又釋放了大量的整數,用于緩存這些整數的內存就不能再分配給浮點數。
4、介紹一下except的用法和作用?
try…except…except…[else…][finally…]
-- 執行try下的語句,如果引發異常,則執行過程會跳到except語句。對每個except分支順序嘗試執行,如果引發的異常與except中的異常組匹配,執行相應的語句。如果所有的except都不匹配,則異常會傳遞到下一個調用本代碼的最高層try代碼中。
-- try下的語句正常執行,則執行else塊代碼。如果發生異常,就不會執行
-- 如果存在finally語句,最后總是會執行。
5、如何用Python來進行查詢和替換一個文本字符串?
可以使用re模塊中的sub()函數或者subn()函數來進行查詢和替換,比replace的功能更強大!!!
格式:sub(replacement, string[,count=0])(replacement是被替換成的文本,string是需要被替換的文本,count是一個可選參數,指最大被替換的數量)
import re
p=re.compile("blue|white|red")
print(p.sub('colour','blue socks and red shoes'))
print(p.sub('colour','blue socks and red shoes',count=1))
subn()方法執行的效果跟sub()一樣,不過它會返回一個二維數組,包括替換后的新的字符串和總共替換的數量
6、有沒有一個工具可以幫助查找python的bug和進行靜態的代碼分析?
PyChecker是一個python代碼的靜態分析工具,它可以幫助查找python代碼的bug, 會對代碼的復雜度和格式提出警告
Pylint是另外一個工具可以進行codingstandard檢查