回覆列表
  • 1 # 程式設計頌

    Python奇技淫巧

    當釋出python第三方package時, 並不希望程式碼中所有的函式或者class可以被外部import, 在 __init__.py 中新增 __all__ 屬性,

    該list中填寫可以import的類或者函式名, 可以起到限制的import的作用, 防止外部import其他函式或者類

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    frombaseimportAPIBase

    fromclientimportClient

    fromdecoratorimportinterface, export, stream

    fromserverimportServer

    fromstorageimportStorage

    fromutilimport(LogFormatter, disable_logging_to_stderr,

    enable_logging_to_kids, info)

    __all__ = ["APIBase","Client","LogFormatter","Server",

    "Storage","disable_logging_to_stderr","enable_logging_to_kids",

    "export","info","interface","stream"]

    with的魔力

    with語句需要支援 上下文管理協議的物件 , 上下文管理協議包含 __enter__ 和 __exit__ 兩個方法. with語句建立執行時上下文需要透過這兩個方法執行 進入和退出 操作.

    其中 上下文表達式 是跟在with之後的表示式, 該表示大返回一個上下文管理物件

    # 常見with使用場景

    withopen("test.txt","r")asmy_file:# 注意, 是__enter__()方法的返回值賦值給了my_file,

    forlineinmy_file:

    print line

    詳細原理可以檢視這篇文章, 淺談 Python 的 with 語句

    知道具體原理, 我們可以自定義支援上下文管理協議的類, 類中實現 __enter__ 和 __exit__ 方法

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    classMyWith(object):

    def__init__(self):

    print"__init__ method"

    def__enter__(self):

    print"__enter__ method"

    returnself# 返回物件給as後的變數

    def__exit__(self, exc_type, exc_value, exc_traceback):

    print"__exit__ method"

    ifexc_tracebackisNone:

    print"Exited without Exception"

    returnTrue

    else:

    print"Exited with Exception"

    returnFalse

    deftest_with():

    withMyWith()asmy_with:

    print"running my_with"

    print"------分割線-----"

    withMyWith()asmy_with:

    print"running before Exception"

    raiseException

    print"running after Exception"

    if__name__ =="__main__":

    test_with()

    執行結果如下:

    __init__ method

    __enter__ method

    running my_with

    __exit__ method

    ExitedwithoutException

    ------分割線-----

    __init__ method

    __enter__ method

    running before Exception

    __exit__ method

    ExitedwithException

    Traceback(most recent call last):

    File"bin/python", line34,in

    exec(compile(__file__f.read(), __file__, "exec"))

    File"test_with.py", line33,in

    test_with()

    File"test_with.py", line28,intest_with

    raiseException

    Exception

    證明了會先執行 __enter__ 方法, 然後呼叫with內的邏輯, 最後執行 __exit__ 做退出處理, 並且, 即使出現異常也能正常退出

    filter的用法

    相對 filter 而言, map和reduce使用的會更頻繁一些, filter 正如其名字, 按照某種規則 過濾 掉一些元素

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    lst = [1,2,3,4,5,6]

    # 所有奇數都會返回True, 偶數會返回False被過濾掉

    print filter(lambda x: x % 2!=0, lst)

    #輸出結果

    [1,3,5]

    一行作判斷

    當條件滿足時, 返回的為等號後面的變數, 否則返回else後語句

    lst = [1,2,3]

    new_lst = lst[0]iflstisnotNoneelseNone

    printnew_lst

    # 列印結果

    1

    裝飾器之單例

    使用裝飾器實現簡單的單例模式

    # 單例裝飾器

    defsingleton(cls):

    instances = dict() # 初始為空

    def_singleton(*args, **kwargs):

    ifclsnotininstances:#如果不存在, 則建立並放入字典

    instances[cls] = cls(*args, **kwargs)

    returninstances[cls]

    return_singleton

    @singleton

    classTest(object):

    pass

    if__name__ =="__main__":

    t1 = Test()

    t2 = Test()

    # 兩者具有相同的地址

    printt1, t2

    staticmethod裝飾器

    類中兩種常用的裝飾, 首先區分一下他們

    普通成員函式, 其中第一個隱式引數為 物件

    classmethod裝飾器 , 類方法(給人感覺非常類似於OC中的類方法), 其中第一個隱式引數為 類

    staticmethod裝飾器 , 沒有任何隱式引數. python中的靜態方法類似與C++中的靜態方法

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    classA(object):

    # 普通成員函式

    deffoo(self, x):

    print "executing foo(%s, %s)"% (self, x)

    @classmethod# 使用classmethod進行裝飾

    defclass_foo(cls, x):

    print "executing class_foo(%s, %s)"% (cls, x)

    @staticmethod# 使用staticmethod進行裝飾

    defstatic_foo(x):

    print "executing static_foo(%s)"% x

    deftest_three_method():

    obj = A()

    # 直接呼叫噗通的成員方法

    obj.foo("para")# 此處obj物件作為成員函式的隱式引數, 就是self

    obj.class_foo("para")# 此處類作為隱式引數被傳入, 就是cls

    A.class_foo("para")#更直接的類方法呼叫

    obj.static_foo("para")# 靜態方法並沒有任何隱式引數, 但是要透過物件或者類進行呼叫

    A.static_foo("para")

    if__name__=="__main__":

    test_three_method()

    # 函式輸出

    executing foo(

    executing class_foo(

    executing class_foo(

    executing static_foo(para)

    executing static_foo(para)

    property裝飾器

    定義私有類屬性

    將 property 與裝飾器結合實現屬性私有化( 更簡單安全的實現get和set方法 )

    #python內建函式

    property(fget=None, fset=None, fdel=None, doc=None)

    property有三個方法 getter() , setter() 和 delete() 來指定fget, fset和fdel。 這表示以下這行

    classStudent(object):

    @property #相當於property.getter(score) 或者property(score)

    defscore(self):

    returnself._score

    @score.setter #相當於score = property.setter(score)

    defscore(self, value):

    ifnotisinstance(value, int):

    raiseValueError("score must be an integer!")

    ifvalue 100:

    raiseValueError("score must between 0 ~ 100!")

    self._score = value

    iter魔法

    透過yield和 __iter__ 的結合, 我們可以把一個物件變成可迭代的

    透過 __str__ 的重寫, 可以直接透過想要的形式列印物件

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    classTestIter(object):

    def__init__(self):

    self.lst = [1,2,3,4,5]

    defread(self):

    foreleinxrange(len(self.lst)):

    yieldele

    def__iter__(self):

    returnself.read()

    def__str__(self):

    return",".join(map(str, self.lst))

    __repr__ = __str__

    deftest_iter():

    obj = TestIter()

    fornuminobj:

    printnum

    printobj

    if__name__ =="__main__":

    test_iter()

    神奇partial

    partial使用上很像C++中仿函式(函式物件).

    在stackoverflow給出了類似與partial的執行方式

    defpartial(func, *part_args):

    defwrapper(*extra_args):

    args = list(part_args)

    args.extend(extra_args)

    returnfunc(*args)

    returnwrapper

    利用用閉包的特性繫結預先繫結一些函式引數, 返回一個可呼叫的變數, 直到真正的呼叫執行

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    fromfunctoolsimportpartial

    defsum(a, b):

    returna + b

    deftest_partial():

    fun = partial(sum, 2)# 事先繫結一個引數, fun成為一個只需要一個引數的可呼叫變數

    printfun(3)# 實現執行的即是sum(2, 3)

    if__name__ =="__main__":

    test_partial()

    # 執行結果

    5

    神秘eval

    eval我理解為一種內嵌的python直譯器(這種解釋可能會有偏差), 會解釋字串為對應的程式碼並執行, 並且將執行結果返回

    看一下下面這個例子

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    deftest_first():

    return3

    deftest_second(num):

    returnnum

    action = { # 可以看做是一個sandbox

    "para":5,

    "test_first": test_first,

    "test_second": test_second

    }

    deftest_eavl():

    condition = "para == 5 and test_second(test_first) > 5"

    res = eval(condition, action) # 解釋condition並根據action對應的動作執行

    printres

    if__name__ =="_

    exec

    exec在Python中會忽略返回值, 總是返回None, eval會返回執行程式碼或語句的返回值

    exec 和 eval 在執行程式碼時, 除了返回值其他行為都相同

    在傳入字串時, 會使用 compile(source, "

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    deftest_first():

    print"hello"

    deftest_second():

    test_first()

    print"second"

    deftest_third():

    print"third"

    action = {

    "test_second": test_second,

    "test_third": test_third

    }

    deftest_exec():

    exec"test_second"inaction

    if__name__ =="__main__":

    test_exec() # 無法看到執行結果

    getattr

    getattr(object, name[, default]) Return the value of

    the named attribute of object. name must be a string. If the string is

    the name of one of the object’s attributes, the result is the value of

    that attribute. For example, getattr(x, ‘foobar’) is equivalent to

    x.foobar. If the named attribute does not exist, default is returned if

    provided, otherwise AttributeError is raised.

    透過string型別的name, 返回物件的name屬性(方法)對應的值, 如果屬性不存在, 則返回預設值, 相當於object.name

    # 使用範例

    classTestGetAttr(object):

    test = "test attribute"

    defsay(self):

    print"test method"

    deftest_getattr():

    my_test = TestGetAttr()

    try:

    printgetattr(my_test,"test")

    exceptAttributeError:

    print"Attribute Error!"

    try:

    getattr(my_test, "say")()

    exceptAttributeError:# 沒有該屬性, 且沒有指定返回值的情況下

    print"Method Error!"

    if__name__ =="__main__":

    test_getattr()

    # 輸出結果

    test attribute

    test method

    命令列處理

    defprocess_command_line(argv):

    """

    Return a 2-tuple: (settings object, args list).

    `argv` is a list of arguments, or `None` for ``sys.argv[1:]``.

    """

    ifargvisNone:

    argv = sys.argv[1:]

    # initialize the parser object:

    parser = optparse.OptionParser(

    formatter=optparse.TitledHelpFormatter(width=78),

    add_help_option=None)

    # define options here:

    parser.add_option( # customized description; put --help last

    "-h","--help", action="help",

    help="Show this help message and exit.")

    settings, args = parser.parse_args(argv)

    # check number of arguments, verify values, etc.:

    ifargs:

    parser.error("program takes no command-line arguments; "

    ""%s" ignored."% (args,))

    # further process settings & args if necessary

    returnsettings, args

    defmain(argv=None):

    settings, args = process_command_line(argv)

    # application code here, like:

    # run(settings, args)

    return0# success

    if__name__ =="__main__":

    status = main()

    sys.exit(status)

    讀寫csv檔案

    # 從csv中讀取檔案, 基本和傳統檔案讀取類似

    importcsv

    withopen("data.csv","rb")asf:

    reader = csv.reader(f)

    forrowinreader:

    printrow

    # 向csv檔案寫入

    importcsv

    withopen("data.csv","wb")asf:

    writer = csv.writer(f)

    writer.writerow(["name","address","age"])# 單行寫入

    data = [

    ( "xiaoming ","china","10"),

    ( "Lily","USA","12")]

    writer.writerows(data) # 多行寫入

    各種時間形式轉換

    只發一張網上的圖, 然後差文件就好了, 這個是記不住的

    字串格式化

    一個非常好用, 很多人又不知道的功能

    >>>name ="andrew"

    >>>"my name is {name}".format(name=name)

    "my name is andrew"

  • 中秋節和大豐收的關聯?
  • 專家建議初學者學習書法應從智永千字文入手?