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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...