1. 程式人生 > >python面試的100題(20)

python面試的100題(20)

程序模塊化 現在 timeit 停止 elf tools 重用 一份 不可變

76.遞歸函數停止的條件?

遞歸的終止條件一般定義在遞歸函數內部,在遞歸調用前要做一個條件判斷,根據判斷的結果選擇是繼續調用自身,還是return;返回終止遞歸。
終止的條件:
1、判斷遞歸的次數是否達到某一限定值
2、判斷運算的結果是否達到某個範圍等,根據設計的目的來選擇

參考地址:https://blog.csdn.net/weixin_43527495/article/details/84841368

77.python寫一個匿名函數求兩個數的和

def sum(a,b):
   c=a+b
   return c

if __name__=="__main__":
   print
(sum(2,4)) a=lambda x,y: x+y print(a(1,2)) #使用匿名函數的實現方法

結果為:6,3

參考地址:https://www.cnblogs.com/wc554303896/p/7710974.html

設計模式

79.對設計模式的理解,簡述你了解的設計模式?

設計模式是經過總結,優化的,對我們經常會碰到的一些編程問題的可重用解決方案。一個設計模式並不像一個類或一個庫那樣能夠直接作用於我們的代碼,反之,設計模式更為高級,它是一種必須在特定情形下實現的一種方法模板。 常見的是工廠模式和單例模式

81.單例模式的應用場景有那些?

單例模式應用的場景一般發現在以下條件下: 資源共享的情況下,避免由於資源操作時導致的性能或損耗等,如日誌文件,應用配置。 控制資源的情況下,方便資源之間的互相通信。如線程池等,1,網站的計數器 2,應用配置 3.多線程池 4數據庫配置 數據庫連接池 5.應用程序的日誌應用...

82.用一行代碼生成[1,4,9,16,25,36,49,64,81,100]

print([x*x for x in range(1, 11)])

83.對裝飾器的理解,並寫出一個計時器記錄方法執行性能的裝飾器?

裝飾器本質上是一個callable object ,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。

import time
from functools import wraps

def timeit(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.clock()
        ret = func(*args, **kwargs)
        end = time.clock()
        print(used:,end-start)
        return ret
    
    return wrapper
@timeit
def foo():
    print(in foo()foo())

84.解釋以下什麽是閉包?

在函數內部再定義一個函數,並且這個函數用到了外邊函數的變量,那麽將這個函數以及用到的一些變量稱之為閉包。

85.函數裝飾器有什麽作用?

裝飾器本質上是一個callable object,它可以在讓其他函數在不需要做任何代碼的變動的前提下增加額外的功能。裝飾器的返回值也是一個函數的對象,它經常用於有切面需求的場景。比如:插入日誌,性能測試,事務處理,緩存。權限的校驗等場景,有了裝飾器就可以抽離出大量的與函數功能本身無關的雷同代碼並發並繼續使用。

86.生成器,叠代器的區別?

叠代器是遵循叠代協議的對象。用戶可以使用 iter() 以從任何序列得到叠代器(如 list, tuple, dictionary, set 等)。另一個方法則是創建一個另一種形式的叠代器 —— generator 。要獲取下一個元素,則使用成員函數 next()(Python 2)或函數 next() function (Python 3) 。當沒有元素時,則引發 StopIteration 此例外。若要實現自己的叠代器,則只要實現 next()(Python 2)或 __next__()( Python 3)

生成器(Generator),只是在需要返回數據的時候使用yield語句。每次next()被調用時,生成器會返回它脫離的位置(它記憶語句最後一次執行的位置和所有的數據值)

區別: 生成器能做到叠代器能做的所有事,而且因為自動創建iter()和next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節省內存。除了創建和保存程序狀態的自動方法,當發生器終結時,還會自動拋出StopIteration異常。

87.X是什麽類型?

X= (i for i in range(10))
X是 generator類型

88.請用一行代碼 實現將1-N 的整數列表以3為單位分組

N =100
print ([[x for x in range(1,100)] [i:i+3] for i in range(0,100,3)])

89.Python中yield的用法?

yield就是保存當前程序執行狀態。你用for循環的時候,每次取一個元素的時候就會計算一次。用yield的函數叫generator,和iterator一樣,它的好處是不用一次計算所有元素,而是用一次算一次,可以節省很多空間,generator每次計算需要上一次計算結果,所以用yield,否則一return,上次計算結果就沒了

面向對象

90.Python中的可變對象和不可變對象?

什麽是可變/不可變對象

  • 不可變對象,該對象所指向的內存中的值不能被改變。當改變某個變量時候,由於其所指的值不能被改變,相當於把原來的值復制一份後再改變,這會開辟一個新的地址,變量再指向這個新的地址。

  • 可變對象,該對象所指向的內存中的值可以被改變。變量(準確的說是引用)改變後,實際上是其所指的值直接發生改變,並沒有發生復制行為,也沒有開辟新的出地址,通俗點說就是原地改變

Python中,數值類型(intfloat)、字符串str、元組tuple都是不可變類型。而列表list、字典dict、集合set是可變類型。

參考地址:https://www.cnblogs.com/sun-haiyu/p/7096918.html

91.Python的魔法方法

參考地址:https://blog.csdn.net/qq_38520096/article/details/79237593

92.面向對象中怎麽實現只讀屬性?

只讀屬性

1.概念:一個屬性(一般指實例屬性),只能讀取,不能寫入。

2.應用場景:有些屬性,只限在內部根據不同場景進行修改,而對外界來說,不能修改,只能讀取。

比如:電腦類的網速屬性,網絡狀態屬性

3.方式1:方案:全部隱藏(私有化,既不能讀,也不能寫。),部分公開(公開讀的操作)

具體實現:私有化(通過“屬性前置雙下劃線”實現。)部分公開:(通過公開的方法)

class Person:
    def __init__(self):
        self.__age = 18
    def getAge(self):
        return self.__age

p1 = Person()
print(p1.getAge())
p1.__age = 99
print(p1.__age)

優化方案:裝飾器@porperty。作用:將一些“屬性的操作方法”關聯到某一個屬性當中。

class Person(object):
    def __init__(self):
        self.__age = 18

    # 主要作用就是,可以以使用屬性的方式,來使用這個方法。
    @property
    def age(self):
        return self.__age

p1 = Person()
print(p1.age)
p1.age = 1
print(p1.age)

概念補充:經典類:沒有繼承(object)

新式類:繼承(object)

python2.x版本中定義一個類時,默認不繼承(object)

python3.x版本中定義一個類時,默認繼承(object)

建議使用:新式類

class Person:
    pass

print(Person.__bases__)

class Man:
    pass

print(Man.__bases__)

# 在python2.x版本中,如果定義一個類。沒有顯示的繼承自object,那麽這個類就是一個經典類。必須顯示的繼承自object,它才是一
# 個新式類

# 在python3.x版本中,如果直接定義一個類,會隱式的繼承object,默認情況下,就已經是一個新式類。
class Person(object):
#     def __init__(self):
#
#         self.__age = 18
#     def get_age(self):
#         print("-----, getage")
#         return self.__age
#
#     def set_age(self, value):
#         print("-----, setage")
#         self.__age = value
#
#     age = property(get_age, set_age)
#
# p = Person()
#
# print(p.age)
#
# p.age = 90
# print(p.age)
# print(p.__dict__)

5.property在新式類和經典類中的使用方法。

在經典類中使用property方法,只能關聯讀取方法。不能關聯寫入、刪除這些方法。能寫不能用。

#_*_encoding:utf-8_*_

# --------------------------------------------propert在新式類中的兩種使用方法-------------------------------------------

# property 第一種使用方式


# class Person(object):
#     def __init__(self):
#
#         self.__age = 18
#     def get_age(self):
#         print("-----, getage")
#         return self.__age
#
#     def set_age(self, value):
#         print("-----, setage")
#         self.__age = value
#
#     age = property(get_age, set_age)
#
# p = Person()
#
# print(p.age)
#
# p.age = 90
# print(p.age)
# print(p.__dict__)


# property 第二種使用方式

# class Person(object):
#     def __init__(self):
#         self.__age = 18
#     @property
#     def age(self):
#         print("-----, get")
#         return self.__age
#
#     @age.setter
#     def age(self, value):
#         print("-----, set")
#         self.__age = value
#
#
# p = Person()
# print(p.age)
#
# p.age = 100
# print(p.age)


# --------------------------------------------propert在經典類中的兩種使用方法-------------------------------------------

# property 第在經典類中的第一種使用方式


# class Person(object):
#     def __init__(self):
#         self.__age = 18
#
#     def get_age(self):
#         print("-----, getage")
#         return self.__age
#
#     def set_age(self, value):
#         print("-----, setage")
#         self.__age = value
#
#     age = property(get_age, set_age)
#
# p = Person()
#
# print(p.age)
#
# p.age = 90
# print(p.age)
# print(p.__dict__)


# property 第在經典類中的第二種使用方式


class Person(object):
    def __init__(self):
        self.__age = 18
    @property
    def age(self):
        print("-----, get")
        return self.__age

    @age.setter
    def age(self, value):
        print("-----, set")
        self.__age = value


p = Person()
print(p.age)

p.age = 100
print(p.age)

print(p.__dict__)

6.只讀屬性設置方式2

class Person(object):
    # 當我們通過實例.屬性 = 值,給一個實例增加一個屬性。或者說,修改一下屬性的值的時候,都用調用這個方法。
    # 在這個方法內部才會真正的把這個屬性以及對應的數據,給存儲到__dict__字典裏面。
    def __setattr__(self, key, value):
        print(key, value)

        #1. 判定key是否是我們要設置的只讀屬性的名稱
        if key == "age" and key in self.__dict__.keys():
            print("這個屬性是只讀屬性,不能設置數據")
        #2.如果說不是這個只讀屬性的名稱,真正的添加到這個實例裏面去。
        else:
            self.__dict__[key] = value
p1 = Person()
p1.age = 18
print(p1.age)
p1.age = 999
print(p1.age)
p1.lala = 100
print(p1.lala)

print(p1.__dict__)

參考地址:https://blog.csdn.net/u010962876/article/details/80740578

93.談談你對面向對象的理解?

所謂的面向對象就是將我們的程序模塊化,對象化,把具體事物的特性屬性和通過這些屬性來實現一些動作的具體方法放到一個類裏面,這就是封裝。封裝是我們所說的面相對象編程的特征之一。除此之外還有繼承和多態。繼承有點類似與我們生物學上的遺傳,就是子類的一些特征是來源於父類的,兒子遺傳了父親或母親的一些性格,或者相貌,又或者是運動天賦。有點種瓜得瓜種豆得豆的意思。面向對象裏的繼承也就是父類的相關的屬性,可以被子類重復使用,子類不必再在自己的類裏面重新定義一回,父類裏有點我們只要拿過來用就好了。而對於自己類裏面需要用到的新的屬性和方法,子類就可以自己來擴展了。當然,會出現一些特殊情況,就是我們在有一些方法在父類已經定義好了,但是子類我們自己再用的時候,發現,其實,我們的雖然都是計算工資的,但是普通員工的工資計算方法跟經理的計算方法是不一樣的,所以這個時候,我們就不能直接調用父類的這個計算工資的方法了。這個時候我們就需要用到面向對象的另一個特性,多態。對,就是多態,我們要在子類裏面把父類裏面定義計算工資的方法在子類裏面重新實現一遍。多態包含了重載和重寫。重寫很簡單就是把子類從父親類裏繼承下來的方法重新寫一遍,這樣,父類裏相同的方法就被覆蓋了,當然啦,你還是可以通過super.CaculSalary方法來調用父類的工資計算方法。而重載就是類裏面相同方法名,不同形參的情況,可以是形參類型不同或者形參個數不同,或者形參順序不同,但是不能使返回值類型不同。

參考地址:https://blog.csdn.net/xukun5137/article/details/46792287

python面試的100題(20)