Python系列6之面向對象

来源:http://www.cnblogs.com/huwentao/archive/2017/06/21/7055180.html
-Advertisement-
Play Games

目錄 生成器和迭代器 字元串格式化 內置函數vars 反射 面向對象編程 一. 生成器和迭代器 1. 生成器 生成器具有一種生成的能力,它僅僅代表著一種生成的能力,當我們需要使用的時候,才會通過迭代器去生成它。因為他只代表這一種生成的能力,因此,生成器比較節省記憶體,它一般通過yield來區分生成的位 ...


目錄

  • 生成器和迭代器
  • 字元串格式化
  • 內置函數vars
  • 反射
  • 面向對象編程

一. 生成器和迭代器

    1. 生成器

    生成器具有一種生成的能力,它僅僅代表著一種生成的能力,當我們需要使用的時候,才會通過迭代器去生成它。因為他只代表這一種生成的能力,因此,生成器比較節省記憶體,它一般通過yield來區分生成的位置。通過next來找到下一個位置。

# 當直接去執行genetor函數的時候,會先返回一個1,然後就退出了,因為遇到了yield
# 當用一個next之後就會執行2. 然後繼續退出
# 也就是說yield其實是生成器的一個地址保存機制,只有通過next才會使他的地址指向下一個yield

def genetor():
    print(1)
    yield 1

    print(2)
    yield 2

    print(3)
    yield 3

    print(4)
    yield 4
obj=genetor()
a = obj.__next__()
b = obj.__next__()
c = obj.__next__()
d = obj.__next__()

  書寫一個xrange函數

def xrange(args):
    value = 0
    while True:
        if value >= args:
            return
        else:
            yield  value
            value += 1
for i in xrange(5):
    print(i)

  2. 迭代器  

    迭代器代表這個一種訪問的能力,他能夠通過一次次的next去迭代生成器產生的對象,因此,他能夠得到我們想要得到的數據。for迴圈就是一種迭代器。如上面的代碼,我們可以通過for迴圈去迭代生成器。

二. 字元串格式化

  1. 字元串的格式化

    字元串的格式化比拼接的方式更加有效

    字元串的格式化更加的方便

  2. %格式化

# %的使用格式,[]裡面的內容都可以省略

%[(name)][flags][width].[precision]typecode
[(name)]
 格式:%[(name)][flags][width].[precision]typecode
 
 (name):        可選的,用於選擇指定的key
 flags:          輸入的格式是左對齊還是右對齊,和width一塊使用,
    +           右對齊, 正數前面加+號, 負數前面加--           不變,就是左對齊
    空格         不變,就是右對齊
    0           右對齊,前面填充0
 width          可選,占有的寬度
 .precision     小數點後保留的位數
 typecode
    s           字元串
    f           有精度的數
    d           整數

  事例:

字元串
s1 = "I am %+10d, age %-10d, % 10d %010d" % (10, 10, 10, 10)
s2 = "I am %+10d, age %-10d, % 10d %010d" % (-10, -10, -10, -10)
print(s1)
print(s2)


結果:
I am        +10, age 10        ,         10 0000000010
I am        -10, age -10       ,        -10 -000000010
整數
# 常用事例:

s1 = "I am %s" % "hu"
s2 = "I am %(name)s, age%(age)s" % {"name": "hu", "age": 13}
s3 = "3.335 + 4.2345 = %2.f" % 7.23566
print(s1, s2, s3)

  3. format格式化的常用方法

  [[fill]align][sign][#][0][width][,][.precision][type] 這個是format的格式,很多和%都是一樣的,下麵只列舉一下關於它的常見用法

s1 = "i am {}, {}, {}".format("hu", "zhou", "12")

s1 = "I am {}, {}, {}".format(*["hu", "zhou", "12"])

s1 = "I am {0}, {1}, {0}".format("seven", 18)

s1 = "I am {0}, {1}, {0}".format(*["seven", 19])

s1 = "I am {name}, {age}, {name}".format(name="hu", age=11)

s1 = "I am {name}, {age}, {name}".format(**{"name":"hu", "age":11})

s1 = "I am {:s}, {:d}, {:f}".format("hu", 18, 1823.923)

s1 = "{:b},{:x},{:o}".format(10,10,10)

s1 = "{:#b},{:#x},{:#o}".format(10,10,10)

三. 內置函數vars

#  內置函數的一些預設的變數

print(vars())
{'__file__': 'C:/Users/zhou/PycharmProjects/fullstack2/6_20/test.py', '__doc__': None, '__cached__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__package__': None, '__name__': '__main__', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000063B24C4F98>}

  1.  __file__      當前工作的環境的絕對路徑

  2. __name__    如果是在當前工作目錄,則返回的是__main__, 如果是導入的模塊,返回的就是模塊的名字

  3. __packge__ 

  4. __doc__      這個變數保存的是這個文件的說明,也就是在文件開頭部分對這個文件功能的說明

  5. __cached__  這個是緩存,如果是導入的模塊就會有緩存

  6. __builtins__  這個是內置函數

'''
這個是一個測試文檔
文檔名稱為test
'''
import index
print(index.__name__)
print(__name__)
print(__file__)
print(__doc__)
print(index.__cached__)


顯示結果:
index
__main__
C:/Users/zhou/PycharmProjects/fullstack2/6_20/test.py

這個是一個測試文檔
文檔名稱為test

C:\Users\zhou\PycharmProjects\fullstack2\6_20\__pycache__\index.cpython-35.pyc

四. 反射

  1. 反射的定義

    反射就是通過字元串的形式去某個對象中操作它的成員。

  2.  __import__方法和import的區別

    <1>. __import__可以通過字元串導入模塊

    <2>. import 不能通過字元串來導入模塊

      簡單的import和__import__

# 此處s3是一個函數的名字
# 對於字元串,直接import導入會報錯,
# 需要用__import__去導入,就相當於是import s3 


# import "s3"
module = __import__("s3")
module.f3()

      擴展的__import__, 當我們需要導入層級的模塊的時候,需要用到fromlist參數

# lib目錄下有個模塊order,要導入的話就需要以下方法

module = __import__("lib.order", fromlist=True)
print(module.add_order())

  3. 反射的方法

    <1>. hasattr(模塊, 關鍵字)     判斷關鍵字是否在模塊中,在的話返回true,不在的話返回false

    <2>. getattr(模塊, 關鍵字)     如果關鍵字是一個函數,則返回函數,如果是一個變數,就返回變數(裡面的關鍵字傳遞的都是字元串,如果是函數,字元串預設是使用不了的,通過這個函數可以轉換成使用的函數)

    <3>. setattr(模塊, 關鍵字, 值)     往模塊中加入關鍵字,加入的可以是變數, 可以是函數,加入和刪除都是在記憶體中完成的,並不會影響文件的內容

    <4>. delattr(模塊,關鍵字)     從模塊中刪除關鍵字

s3的內容
def f1():
    print("f1")

=============================
# 導入s3,判斷關鍵字是否在s3中
import s3
ret1 = hasattr(s3, "f1")
ret2 = hasattr(s3, "f11")
print(ret1)
print(ret2)

結果:
True
False
hasattr()
# 導入模塊,通過字元串得到模塊內函數
# 然後執行函數
# 字元串f1 是執行不了的,只能通過getattr得到函數在執行

import s3
func = getattr(s3, 'f1')
func()
getattr()
# setattr傳遞的是一個鍵值對,而hasattr判斷的只是鍵,而不是值,
# 因為剛開始還沒有這個“name”,所以返回的是false,通過setattr設置了這個鍵,所以返回的是True

import s3
print(hasattr(s3, "name"))
setattr(s3, "name", "hu")
print(hasattr(s3, "name"))

結果:
False
True
setattr()
# 開始f1是存在的,所以返回True
# 通過del刪除之後,在返回的就是False了

import s3
print(hasattr(s3, "f1"))
delattr(s3, "f1")
print(hasattr(s3, "f1"))

結果:
True
False
delattr()
url = input("請輸入url:")
target_module, target_func = url.split("/")
print(target_func, target_module)
module = __import__("lib."+target_module, fromlist=True)
print(module)
if hasattr(module, target_func):
    # module.target_func()
    target_func = getattr(module, target_func)
    target_func()
else:
    print("404")
Python實例(基於web框架的路由系統)

五. 面向對象編程

  1. 編程

    其實在我們日常生活中,編程的方式有很多,例如:面向過程,面向對象,或者是函數式編程,他們的區別還蠻大的,但是最終的目的只有一個,那就是簡化工作量。就像是蓋房子,面向過程就是我要自己去買磚買瓦,自己壘砌,然後函數式編程就是我自己買磚買瓦,然後找木匠工人給我做,面向對象就是,我要直接買一套房子,省的自己做了。

  2. 面向對象編程

    (1). 定義類

      類是什麼呢?類嚴格的定義是由某種特定的元數據所組成的內聚的包。他是由多個函數共同組成的為了完成某種功能的組合。既然有了函數,為什麼還要類呢?當我們的函數出現大量的相同的參數或者相同的功能的時候,就需要類來簡化其操作了

# 關鍵字class創建了一個類,類名為Foo
# 定義了三個方法,__init__ f1和f2 
# 方法裡面的self為預設的參數,必須帶

class Foo:
    def __init__(self):
        self.Name = "hu"
    def f1(self):
        print("f1")
    def f2(self):
        print("f1")

    (2). 執行類(創建對象)

      對象是什麼呢?在Python中,一切皆對象,當我們創建了一類數據之後,他只是一類數據,其中的方法,參數都都是泛華的東西,我們需要有一個對象來對其進行實例化。也就是說,當我們說:這有個人。你肯定不知道他是誰,因為他只代表了一類數據,當我們說:他是李剛,你就會恍然大悟,哦 ,他是李剛啊,這是因為我們吧類實例化了。

      __init__方法用來創建對象和封裝內容

      每一個方法中的self變數都是Python中預設添加的,用來傳遞對象的。當我們創建了一個obj對象的時候,會自動的調用類中的__init__方法,然後把obj當做參數傳遞給self。

# 通過類名加括弧去創建一個對象,並用對象去調用方法

class Foo:
    def __init__(self):
        self.Name = "hu"
    def f1(self):
        print("f1")
    def f2(self):
        print("f1")

obj = Foo()
obj.f1()

      創建對象的圖示:都在記憶體中,創建一個對象的時候,預設的會去執行類中的__init__方法,通過init方法來產生右邊的對象。

    

    (3). 三大特性

      在面向對象的語言中,一般都具有以下三種特性,封裝,繼承和多態。也正是因為這樣,才構成了一個龐大的面向對象的系統,以至於你可以通過它來表述任何事物。千變萬化。

       <1>. 封裝

        封裝就是把一系列相同的功能封裝到對象中,從而簡化類的方法。在介紹封裝之前,我們先來比較一下封裝和不封裝的區別。

        由下麵的例子我們就可以看出來,封裝其實就是把一些重覆的量統一的在一個地方進行定義,然後在利用。

#  沒有封裝數據
class Person:
    def chifan(self, name, age, gender):
        print(name, "吃飯")
    def shuijiao(self, name, age, gender):
        print(name, "睡覺")
    def dadoudou(self, name, age, gender):
        print(name,"打豆豆")
沒有封裝
class Person:
    def __init__(self, name, age, gender):
        self.Name = name
        self.Age = age
        self.Gender = gender
    def chifan(self):
        print(self.Name,"吃飯")
    def shujiao(self):
        print(self.Name,"睡覺")
    def dadoudou(self):
        print(self.Name,"打豆豆")
封裝

        使用場景:

          a. 當同一類型的方法具有多個模板的時候,直接封裝成對象即可
          b. 把類當做模板,創建多個對象(對象內封裝的數不一樣)

          例:定義了一個類Person,用__init__去封裝了三個參數,以供下麵的兩個方法來調用,通過pickle模塊來存檔。

import pickle
class Person:
    def __init__(self, name, age, weight):
        self.Name = name
        self.Age = age
        self.Weight = weight
    def chi(self):
        self.Weight += 2
    def jianshen(self):
        self.Weight -= 1
ret = pickle.load(open('youxi', 'rb'))
if ret:
    print(ret.Weight)
    obj1 = Person(ret.Name, ret.Age, ret.Weight)
else:
    obj1 = Person('xiaoming', 12, 200)
    obj1.chi()
    obj1.chi()
    obj1.chi()
    obj1.jianshen()
pickle.dump(obj1, open('youxi', 'wb'))

       <2>. 繼承

        我們都聽說過子承父業,其實繼承就是這個意思,當我們定義了幾個類之後,發現這幾個類都有一些共同的屬性和方法,這個時候我們就可以把這幾個共同的屬性和方法定義成一個類來當做這幾個類的父親,然後這幾個類就可以繼承父親的屬性和方法來當做自己的方法。如下麵這個例子,定義了三個類,一個父類,一個兒子,一個女兒,父類的方法有吃和喝,兒子的方法是票,女兒的方法是賭,當兒子繼承了父親,就會把父親的方法繼承下來,自然也就會了吃和喝,女兒也一樣。

class Parent:
     def chi(self):
         print("")
     def he(self):
         print("")
class son(Parent):
    def piao(self):
        print("")
    
class nver(Parent):
    def du(self):
        print("")
        
obj = son()
obj.chi()
obj.he()
obj.piao()
obj1 = nver()
obj1.chi()
obj1.he()
obj1.du()
View Code

        繼承的規則

        1. 子類會預設的繼承父類的所有方法

        2. 如果子類和父類有同樣的方法,會優先的去用子類的方法

        3. Python中可以繼承多個類(這個是Python的特點, C#和java都不具備)

        Python中繼承多個類的順序規則

        因為Python中可以多繼承,因此當子繼承父類的時候,它的規則一般是先執行左邊的,後執行右邊的,當有嵌套的時候,每次還要重新回到子類中去遞歸查找。如下麵的例子

 

     例:當子類中的方法沒有的時候就會依次的向上進行查找

# 創建了幾個類,繼承關係如上圖中的一
class A:
    def f1(self):
        print("A")
class B:
    def f1(self):
        print("B")
class C(A):
    def f1(self):
        print("C")

class D(B):
    def f1(self):
        print("D")
class E(C, D):
    def f1(self):
        print("E")
obj = E()
obj.f1()
上圖一
class Hu:
    def f1(self):
        print("Hu")
class A(Hu):
    def f1(self):
        print("A")
class B(Hu):
    def f1(self):
        print("B")
class C(A):
    def f1(self):
        print("C")

class D(B):
    def f1(self):
        print("D")
class E(C, D):
    def f1(self):
        print("E")
obj = E()
obj.f1()
上圖二

       <3>. 多態

         因為在Python傳參的時候本身就沒有類型的約束,因此它本身就是多態的,我們可以把任意的數據傳進去。

    (4). 成員

       方法: 靜態方法(無需使用對象封裝的內容@staticmethod,直接用類進行調用),普通方法(使用對象進行封裝),類方法

       欄位: 靜態欄位(每一個對象都會有一份),普通欄位(使用對象中進行封裝的)

       特性: 只有一種,將方法偽造成欄位

       調用成員的方式:

         1. 如果沒有self, 就用類進行調用

         2. 如果有self, 就用對象進行調用

   3. 異常處理

      在程式執行的過程中,會遇到一些未知的錯誤,但是我們總是希望把這些錯誤的以我們能控的方式返回給用戶,這是就用到了異常處理。

      異常處理的格式:

# 當try後面的語句發生錯誤之後,就會觸發後面的語句,返回一個我們可以控制的錯誤信息

a = input("輸入一個數:")
try:
    a = int(a)
except Exception as e:
    print("出錯了....")

 


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

-Advertisement-
Play Games
更多相關文章
  • 一、使用線程的理由 1、可以使用線程將代碼同其他代碼隔離,提高應用程式的可靠性。 2、可以使用線程來簡化編碼。 3、可以使用線程來實現併發執行。 二、基本知識 1、進程與線程:進程作為操作系統執行程式的基本單位,擁有應用程式的資源,進程包含線程,進程的資源被線程共用,線程不擁有資源。 2、前臺線程和 ...
  • using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace Utils { /// <summary> /// <para> </para> /// 常用 ...
  • WPF簡介 Windows Presentation Foundation(WPF)是微軟新一代圖形系統,運行在.NET Framework 3.0架構下,為用戶界面、2D/3D 圖形、文檔和媒體提供了統一的描述和操作方法。基於DirectX 9/10技術的WPF不僅帶來了前所未有的3D界面,而且其 ...
  • 在.Net框架中,如果您查看所有類型的的基類:System.Object類,將找到如下4個與相等判斷的方法: static Equals() virtual Equals() static ReferenceEquals() virtual GetHashCode() 除此之外,Microsoft已 ...
  • 對於堆排序會涉及一些完全二叉樹知識。對於待排序列{10, 2, 11, 8, 7},把它看成是一顆完全二叉樹,如下圖所示。 堆分為大根堆和小根堆:大根堆表示每個根節點均大於其子節點(L(i) >= L(2i) && L(i) >= L(2i + 1)),小根堆表示每個根節點均小於其子節點(L(i)  ...
  • 1.瀏覽器請求動態頁面過程 2.WSGI Python Web Server Gateway Interface (或簡稱 WSGI,讀作“wizgy”)。 WSGI允許開發者將選擇web框架和web伺服器分開。可以混合匹配web伺服器和web框架,選擇一個適合的配對。比如,可以在Gunicorn ...
  • Given a binary tree, return the inorder traversal of its nodes' values. ...
  • FPGA的設計流程就是利用EDA開發軟體和編程工具對FPGA晶元進行開發的過程。FPGA的開發流程一般下如圖所示,包括電路設計、設計輸入、功能模擬、綜合優化、綜合後模擬、實現、佈線後模擬、板級模擬以及晶元編程與調試等主要步驟。 1. 電路設計 在系統設計之前,首先要進行的是方案論證、系統設計和FPG ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...