Python【day 17-2】面向對象-成員

来源:https://www.cnblogs.com/wangtp/archive/2019/12/11/12020172.html
-Advertisement-
Play Games

'''''' ''' 1、簡述面向對象三大特性並用示例解釋說明?【背寫】 1、封裝 狹義的封裝:把一組屬性封裝到一個對象,創建對象的時候 廣義的封裝:代碼塊,函數、對象、類、模塊-py文件都是封裝 把封裝後的對象看成一個黑盒子,只需要關註輸入和輸出,不必關註黑盒子內部的實現 2、繼承 1、避免代..... ...


''''''
'''
1、簡述面向對象三大特性並用示例解釋說明?【背寫】
    1、封裝
        狹義的封裝:把一組屬性封裝到一個對象,創建對象的時候
        廣義的封裝:代碼塊,函數、對象、類、模塊-py文件都是封裝
                   把封裝後的對象看成一個黑盒子,只需要關註輸入和輸出,不必關註黑盒子內部的實現
    2、繼承
        1、避免代碼的重覆
        2、可擴展
            共有的寫在父類,擴展的時候用子類
    3、多態

2. 面向中的變數分為哪幾種?並用示例說明區別?【背寫】
    1、成員變數
        寫在構造方法中的,前面是self.  局部的意思
    2、類變數(靜態變數)
        寫在類中方法(成員方法)之外的變數,全局的意思
        多個對象共用的

3. 面向對象中方法有哪幾種?並用示例說明區別?【背寫】
    1、成員方法
        1、包括構造方法和普通方法
        2、第一個參數是self
        3、通過對象來直接調用
    2、靜態方法
        1、參數不需要self
        2、寫法是方法名字上面加上一行@staticmethod
        3、通過類名來調用
        4、把它理解成類中的函數即可
    3、類方法
        1、參數只有一個cls,表示可以說傳入類名
        2、寫法是方法名字上面加上一行@classmethos
        3、通過類名來調用
        4、可以在類方法中創建對象,設計模式

4. 面向對象中的屬性有什麼?並用示例說明?
   定義:用方法來表示一個屬性(成員變數)
   寫法:方法名字上面加一行@property
        只有一個參數self
        必須有返回值(屬性取的就是返回值)
   調用:對象名.方法名
         註意方法名字後面不加小括弧
   例子:人的年齡
        1、成員變數中,一般不存儲人的年齡,因為年齡每年都會變
        2、成員變數中,存儲的是人的生日
        3、可以用成員方法,根據生日計算年齡,但是年齡是一個屬性-名稱
           用方法-動詞計算不是特別合適
        4、就引入了用方法的變種--屬性來表示年齡

5. 簡述靜態方法和類方法的區別?
    1、寫法不同
        前者方法名字前面加上@staticmethod
        後者方法名字前面加上@classmethod
    2、參數不同
        前者的參數沒有self
        後者的參數是cls
    3、含義不同
        前者可以理解成類中的函數,不需要傳self,對象
        後者的參數傳入的是類名,主要用於對象的創建,設計模式

'''
6. 面向對象的方法中那個無需傳參數?
    靜態方法無需傳參數
    成員方法self
    類方法cls

7. 面向對象中公有和私有成員,在編寫和調用時有哪些不同?
    1、編寫上
        後者名字前面需要加上__,前者不需要
    2、調用上
        後者不能通過對象直接訪問
        後者可以通過對象調用公有成員方法的形式,訪問私有變數或者私有方法
        (把私有變數或者私有方法寫在公有成員方法中)

        前者可以通過對象直接訪問
# 18.現有50條數據.請使用面向對象的思維來完成這50條數據的分頁工作(升級題)
class Page:
    def __init__(self,lst,pagesize):
        self.lst = lst
        self.pagesize = pagesize
    def start(self):
        '''
        返回第一頁的內容
        '''
    def end(self):
        '''
        返回最後一頁的內容
        '''
    def index(self):
        '''
        返回指定頁的內容
        '''
        page = input('請輸入你要查詢的數據的頁數:')

'''
偽代碼思路:
第一步
1、一共是6條數據,每頁2條,分成3頁
2、輸入頁數1,列印1-2(索引號和值都是1,2)
3、輸入頁數3,列印5-6

第二步
1、一共是5條數據,每頁2條,分成3頁
2、輸入頁數1,列印1-2(索引號和值都是1,2)
3、輸入頁數3,列印5

'''

class Page:
    def __init__(self,lst,pagesize):
        self.lst = lst
        self.pagesize = pagesize
    def start(self):
        '''
        返回第一頁的內容
        '''
        # total_page = len(self.lst)/self.pagesize
        print(self.lst[:self.pagesize])
        return self.lst[:self.pagesize]

    def end(self):
        '''
        返回最後一頁的內容
        '''
        total_page = len(self.lst) / self.pagesize
        # print(total_page)
        if type(total_page) == int:
            print(self.lst[-self.pagesize:])
            return self.lst[-self.pagesize:]
        else:
            result, remainder = divmod(len(self.lst),self.pagesize)
            # print(result)  2 商是2
            # print(remainder) 1 餘數是1
            print(self.lst[-remainder:])  #[5]
            return self.lst[-remainder:]

    def specified_page(self,n):
        print(self.lst[self.pagesize*(n-1):self.pagesize*n])
        return self.lst[self.pagesize*(n-1):self.pagesize*n]

    def index(self):
        '''
        返回指定頁的內容
        '''
        while 1:
            page = input('請輸入你要查詢的數據的頁數,輸入q退出:')
            if page.upper() == 'Q':
                print('退出了')
                break
            elif page == '1':
                self.start()
            elif page == '-1':
                self.end()
            elif page.isdigit() == False:
                print('只能輸入數字,請輸入數字')
            elif int(page) <= (len(self.lst)/self.pagesize)+1 :
                self.specified_page(int(page))
            # elif int(page) > (len(self.lst) / self.pagesize) + 1 :
            #     print('頁碼超出範圍了')
            else:
                print('頁碼超出範圍了')

# li1 = [1,2,3,4,5,6]
li1 = [1,2,3,4,5]
p1 = Page(li1,2)  #一共是5條記錄,每頁2條記錄
p1.index()
print('------------------------18 ')
''''''
'''
19.在昨天最後一題的基礎上.把數據寫入到文件中.並且註冊的時候需要到文件中判斷是否重
復.如果重覆提示不能註冊.(升級題
'''

# 16.    補充代碼:實現用戶註冊和登錄
# class User:
#     def __init__(self,user,pwd):
#         self.user = user
#         self.pwd = pwd

class Account:
    def __init__(self):
        # user_list = []  #存放user對象  這個必須加上self變成成員變數才行
        # self.user_list = []  #存放user對象   #註意點2:這裡必須加self,表示成員變數(可以在方法間使用)

        #新建文件
        # self.f1 = open('acount.txt',mode='w+',encoding='utf-8')  #先w+  後a+  可寫可讀 每次都清空,覆蓋
        self.f1 = open('acount.txt',mode='a+',encoding='utf-8')  #先w+  後a+   可追加可讀
        #1 新建文件,文件對象存儲成成員變數,方便方法間使用

    def register(self): #1 註冊功能
        print('歡迎來到註冊頁面')
        username = input('請輸入你要註冊的登錄用戶名:')
        password = input('請輸入你要註冊的登錄密碼:')
        # u1 = User(username,password)  #新建對象,對象中封裝正確的用戶名和密碼
        # self.user_list.append(u1)  #self.user_list 表示成員變數(可以在方法間使用)
        # print(self.user_list) #[<__main__.User object at 0x00000098C5EDF0C8>]

        #一、先判斷用戶名是否在文件中已經存在
        self.f1.seek(0, 0)  # 1游標到文件開頭   關鍵點1
        #是在第二次運行程式的時候,判斷用戶名是否存在的時候,從歷史註冊用戶名中進行查找、判斷、去重
        for i in self.f1:  # 2 遍歷文件對象,讀取文件中每一行
            if username == i.split('|')[0]:#3 判斷用戶輸入的用戶名和文件中已經存在的用戶名進行比對
                print('用戶名已經存在')
                break  #4,如果已經存在,就跳出整個for迴圈
        else: #5 如果沒有任何break 正常結束,執行else,如果有break,else下麵就不會執行
        # 如果不寫else,即使有break,下麵的內容也會執行; 有沒有else,在break的情況下,執行是完全不同的
            #6 往空白文件中寫入用戶名和密碼
            self.f1.write(username+'|'+password+'\n')
            self.f1.flush()  #7 將寫入的及時刷新到文件
            # self.f1.seek(0,0)  #游標到文件開頭
            # self.f1.close()  #8 先不關閉,如果在這裡關閉,就會報錯
            #ValueError: I/O operation on closed file.

    def login(self): #2 登錄介面
        print('歡迎來到登錄頁面')
        n = 0
        for i in range(3):  #3次重試機會
            username2 = input('請輸入你要登錄的登錄用戶名:')
            password2 = input('請輸入你要登錄的登錄密碼:')
            # for i in self.user_list:   #迴圈遍歷用戶對象  self.user_list表示成員變數(可以在方法間使用)
            self.f1.seek(0, 0)  # 1、游標到文件開頭  關鍵點2
            #2 在用戶輸入用戶名和密碼登錄的時候,需要從文件開頭遍歷已經註冊的用戶名和密碼
            for i in self.f1:   #3 迴圈遍歷文件對象  self.f1表示成員變數(可以在方法間使用)
                # if i.user == username2 and i.pwd == password2:  #關鍵點1 i.user取的是對象的屬性
                if i.split('|')[0].strip() == username2 and i.split('|')[1].strip() == password2:  #
                    #4 strip()是為了去掉換行符
                    #5 把用戶輸入的用戶名密碼和文件中的用戶名密碼進行匹配
                    print('登錄成功')
                    # self.f1.close()  #關閉文件  檢查點
                    #ValueError: I/O operation on closed file.
                    # break  #註意點3  只能退出當層內迴圈
                    return  #註意點4  可以退出內層迴圈和外層迴圈(一次退出2層迴圈)
            else:  #6 這個else必須是和for同級,而不能是和if同級  關鍵點2
                #因為期望結果的每行判斷完,才能說明登錄失敗
                n+=1
                print('登錄失敗,請重新輸入,你還有 %s 次重試機會' % (3-n) )
        self.f1.close()  # 7關閉文件 註意這行代碼的位置  關鍵點3

    def run(self):#3 選擇註冊還是登錄,先註冊,後登錄
        while 1:
            choice = input('請選擇,1表示註冊,2表示登錄,Q表示退出:')
            if choice == '1':
                self.register()  #註意點1  方法前面必須加上self
            elif choice == '2':
                self.login()  #註意點1  方法前面必須加上self
            elif choice.upper() == 'Q':
                print('已經退出了')
                break
            else:
                print('你輸入的不對,請重新輸入')

a1 = Account()
a1.run()
'''
註冊和登錄的邏輯:
1、註冊的時候,把正確的用戶名和密碼,比如:jack/123 存入資料庫(或者對象中,列表中)
   保存之前,先判斷用戶名在文件中是否已經存在,如果重覆提示不能註冊
2、登錄的時候,輸入登錄用戶名和密碼,拿用戶輸入的用戶名和密碼 和之前註冊的用戶名和密碼進行比對
   如果相等匹配,就是登錄成功
   如果不相等不匹配,就是登錄失敗
3、之前是將註冊後的用戶名和密碼存在列表中--記憶體中
   現在需要存在文件中(類似於-持久化到資料庫)

註意點:
1、游標的位置回到文件的開頭
2、關閉文件對象的代碼所在的位置

擴展:
1、能否把對象寫入文件中--不能
   --文件中只能寫入字元串,不能寫入對象
2、先實現用戶名|密碼+換行符 寫入文件
3、註冊用戶名去重--ok

介面的概念:
1、介面可以對外提供服務,對外提供功能,介面是服務端
2、客戶端-發起端發起請求,調用登錄介面
    只需要傳入正確的參數(用戶名和密碼),就可以登錄成功
'''

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 群聊版 安裝 pipinstallgevent-websocket 視圖 #-*-coding:utf-8-*- importjson fromflaskimportFlask,request,render_template fromgeventwebsocket.handlerimportWebS... ...
  • part4 課程介紹 事件 1. 綁定事件的區別 2. 移除綁定事件的方式及區別和相容代碼 3. 事件的三個階段 4. 事件冒泡 5. 為同一個元素綁定多個不同的事件,指向的是同一個事件處理函數 6. 百度的大項目 7. BOM 8. 定時器 9. DOM加強,多個幾個好玩的案例 part3 複習 ...
  • 一、解決什麼問題 1、如果a.js和b.js都引用了common.js,那在打包的時候common.js會被重覆打入到a.js和b.js,造成重覆打包 2、單獨打包common.js對性能有幫助,瀏覽器下載一次後會緩存下來,不會重覆下載 二、未抽取公共代碼的狀況 基於之前代碼,測試如下: 1、在as ...
  • 盒子模型 邊框:border 左邊框:border left 右邊框:border right 上邊框:border top 下邊框:border bottom 複合樣式:border 邊框顏色:border color 邊框寬度:border width 邊框樣式:border style 實線: ...
  • 迴圈可多次執行代碼塊。 JavaScript 迴圈 假如您需要運行代碼多次,且每次使用不同的值,那麼迴圈(loop)相當方便使用。 通常我們會遇到使用數組的例子: 不需要這樣寫: text += cars[0] + "<br>"; text += cars[1] + "<br>"; text += ...
  • 引入CDN,算好需要合併的單元格。 <!DOCTYPE html> <html> <head> <!-- 移動設備 --> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> < ...
  • 簡介 適配器模式(Adapter Pattern)是作為兩個不相容的介面之間的橋梁。這種類型的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。這種模式涉及到一個單一的類,該類負責加入獨立的或不相容的介面功能。 功能展示 場景模擬 外國出差,給筆記本充電,德國有一套德國標準,中國有一套中國標準(國 ...
  • 簡介 裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。 這種模式創建了一個裝飾類,用來包裝原有的類,併在保持類方法簽名完整性的前提下,提供了額外的功能。我們通過下麵的實例來演示裝飾器模 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...