python可變參數與標準輸出的重定位

來源:互聯網
上載者:User

用python的內建函數print時,大家會發現它是支援任意多個參數,也就是說,print的調用參數是不固定的。例如:

print "你好"
print "我是",name
print "現在是", time , " 你在幹什麼呢", name , "!"

 

 這得益與python的“可變參數”,在Python裡,可以使用*和**來設定可變參數,它們的區別是*傳遞一個參數元組,**傳遞一個參數字典,二者可以同時混合使用。混合使用時要加些小心,因為python中他們的次序是重要的。參數歸為4類,不是所有的類別都需要。他們必須按下面的次序定義,不用的可以跳過。
    1)必須的參數
    2)可選的參數
    3)過量的位置參數
    4)過量的關鍵字參數

def funName(a, b=None, *c, **d):

 

    這個次序是必須的,因為*args和**kwargs只接受那些沒有放進來的其他任何參數。沒有這個次序,當你調用一個帶有位置參數的函數,python就不知道哪個值是已聲明參數想要的,也不知道哪個被作為過量參數對待。
    也要注意的是,當函數能接受許多必須的參數和可選的參數,那它只要定義一個過量的參數類型即可。看下面的例子:

 代碼如下 複製代碼

    def add(a, b, c):
        return a + b + c
    >>> add(1, 2, 3)
    6
    >>> add(a=4, b=5, c=6)
    15
    >>> args = (2, 3)
    >>> add(1, *args)
    6
    >>> kwargs={'b': 8, 'c': 9}
    >>> add(a=7, **kwargs)
    24
    >>> add(a=7, *args)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: add() got multiple values for keyword argument 'a'
    >>> add(1, 2, a=7)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: add() got multiple values for keyword argument 'a'

    注意這個例子的最後幾行,特別留意當傳遞一個元組作為可變參數時,是否要顯式的傳遞關鍵字參數。因為python使用次序規則來擴充過量的參數,那位置參數要放在前面。這個例子中,最後兩個調用是相同的,python不能決定那個值是給a的。

    下面舉一個例子來模仿print的實現:

 代碼如下 複製代碼

    >>> import sys
    >>> def myprint(*argv):
        sys.stdout.write(" ".join([str(i) for i in argv]) + "n")
    >>> print "I believe", 2012, "is the end of the world."
    I believe 2012 is the end of the world.
    >>> myprint("I believe", 2012, "is the end of the world.")
    I believe 2012 is the end of the world.
    >>> print "tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012}
    tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}
    >>> myprint("tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012})
    tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}

    print預設是輸出到stdout中,在終端啟動並執行程式,無重新導向的情況下,print輸出到控制台。如果要做代碼裡實現把print的輸出寫入到log檔案中,可以通過修改stdout的檔案對象來實現。同理,重定位標準輸入和標準錯誤輸出分別修改stdin和stderr的檔案對象即可。
    下面的例子捕捉所有print的輸出,讓輸出的每一行前增加一個時間的顯示:

 代碼如下 複製代碼

 

    import sys, time
    class MyOutput():
        def __init__(self, fd):
            self.formatTime()
            self.out = fd
            self.newLine = True
        def formatTime(self):
            return time.strftime("%H:%M:%S  ", time.localtime())
        def write(self, s):
            if self.newLine:
                self.out.write(self.formatTime())
                self.newLine = False
            self.out.write(s)
            if s.endswith("n"):
                self.newLine = True
        def flush(self):
            self.out.flush()
    sys.stdout = MyOutput(sys.stdout)
    print "Program begin."
    mylist = [5, 4, 3, 2, 1]
    print "prev:  ", mylist
    mylist.sort()
    print "after: ", mylist
    time.sleep(3)
    print "Program end."

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.