乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Python 自省指南

       yfmine 2007-02-22



      2002 年 12 月 26 日

      自省揭示了關(guān)于程序?qū)ο蟮挠杏眯畔?。Python 是動(dòng)態(tài)的面向?qū)ο蟮木幊陶Z(yǔ)言,提供了很棒的自省支持。本文展示了該語(yǔ)言的許多能力,從最基本形式的幫助到較為高級(jí)形式的調(diào)查。

      檢查 Python 對(duì)象

      我們好幾次提到了“對(duì)象(object)”這個(gè)詞,但一直沒(méi)有真正定義它。編程環(huán)境中的對(duì)象很象現(xiàn)實(shí)世界中的對(duì)象。實(shí)際的對(duì)象有一定的形狀、大小、重量和其它特征。實(shí)際的對(duì)象還能夠?qū)ζ洵h(huán)境進(jìn)行響應(yīng)、與其它對(duì)象交互或執(zhí)行任務(wù)。計(jì)算機(jī)中的對(duì)象試圖模擬我們身邊現(xiàn)實(shí)世界中的對(duì)象,包括象文檔、日程表和業(yè)務(wù)過(guò)程這樣的抽象對(duì)象。

      類(lèi)似于實(shí)際的對(duì)象,幾個(gè)計(jì)算機(jī)對(duì)象可能共享共同的特征,同時(shí)保持它們自己相對(duì)較小的變異特征。想一想您在書(shū)店中看到的書(shū)籍。書(shū)籍的每個(gè)物理副本都可能有污跡、幾張破損的書(shū)頁(yè)或唯一的標(biāo)識(shí)號(hào)。盡管每本書(shū)都是唯一的對(duì)象,但都擁有相同標(biāo)題的每本書(shū)都只是原始模板的實(shí)例,并保留了原始模板的大多數(shù)特征。

      對(duì)于面向?qū)ο蟮念?lèi)和類(lèi)實(shí)例也是如此。例如,可以看到每個(gè) Python 字符串都被賦予了一些屬性,dir() 函數(shù)揭示了這些屬性。在前一個(gè)示例中,我們定義了自己的 Person 類(lèi),它擔(dān)任創(chuàng)建個(gè)別 Person 實(shí)例的模板,每個(gè)實(shí)例都有自己的 name 和 age 值,同時(shí)共享自我介紹的能力。這就是面向?qū)ο蟆?

      于是在計(jì)算機(jī)術(shù)語(yǔ)中,對(duì)象是擁有標(biāo)識(shí)和值的事物,屬于特定類(lèi)型、具有特定特征和以特定方式執(zhí)行操作。并且,對(duì)象從一個(gè)或多個(gè)父類(lèi)繼承了它們的許多屬性。除了關(guān)鍵字和特殊符號(hào)(象運(yùn)算符,如 +-、*、**、/、%、<> 等)外,Python 中的所有東西都是對(duì)象。Python 具有一組豐富的對(duì)象類(lèi)型:字符串、整數(shù)、浮點(diǎn)、列表、元組、字典、函數(shù)、類(lèi)、類(lèi)實(shí)例、模塊、文件等。

      當(dāng)您有一個(gè)任意的對(duì)象(也許是一個(gè)作為參數(shù)傳遞給函數(shù)的對(duì)象)時(shí),可能希望知道一些關(guān)于該對(duì)象的情況。在本節(jié)中,我們將向您展示如何讓 Python 對(duì)象回答如下問(wèn)題:

      • 對(duì)象的名稱(chēng)是什么?
      • 這是哪種類(lèi)型的對(duì)象?
      • 對(duì)象知道些什么?
      • 對(duì)象能做些什么?
      • 對(duì)象的父對(duì)象是誰(shuí)?

      名稱(chēng)

      并非所有對(duì)象都有名稱(chēng),但那些有名稱(chēng)的對(duì)象都將名稱(chēng)存儲(chǔ)在其 __name__ 屬性中。注:名稱(chēng)是從對(duì)象而不是引用該對(duì)象的變量中派生的。下面這個(gè)示例著重說(shuō)明了這種區(qū)別:



      清單 27. 名稱(chēng)中有什么?
      $ python
                                          Python 2.2.2 (#1, Oct 28 2002, 17:22:19)
                                          [GCC 3.2 (Mandrake Linux 9.0 3.2-1mdk)] on linux2
                                          Type "help", "copyright", "credits" or "license" for more information.
                                          >>> dir()                # The dir() function
                                          [‘__builtins__‘, ‘__doc__‘, ‘__name__‘]
                                          >>> directory = dir      # Create a new variable
                                          >>> directory()          # Works just like the original object
                                          [‘__builtins__‘, ‘__doc__‘, ‘__name__‘, ‘directory‘]
                                          >>> dir.__name__         # What‘s your name?
                                          ‘dir‘
                                          >>> directory.__name__   # My name is the same
                                          ‘dir‘
                                          >>> __name__             # And now for something completely different
                                          ‘__main__‘
                                          

      模塊擁有名稱(chēng),Python 解釋器本身被認(rèn)為是頂級(jí)模塊或主模塊。當(dāng)以交互的方式運(yùn)行 Python 時(shí),局部 __name__ 變量被賦予值 ‘__main__‘。同樣地,當(dāng)從命令行執(zhí)行 Python 模塊,而不是將其導(dǎo)入另一個(gè)模塊時(shí),其 __name__ 屬性被賦予值 ‘__main__‘ ,而不是該模塊的實(shí)際名稱(chēng)。這樣,模塊可以查看其自身的 __name__ 值來(lái)自行確定它們自己正被如何使用,是作為另一個(gè)程序的支持,還是作為從命令行執(zhí)行的主應(yīng)用程序。因此,下面這條慣用的語(yǔ)句在 Python 模塊中是很常見(jiàn)的:



      清單 28. 用于執(zhí)行或?qū)氲臏y(cè)試
      if __name__ == ‘__main__‘:
                                          # Do something appropriate here, like calling a
                                          # main() function defined elsewhere in this module.
                                          main()
                                          else:
                                          # Do nothing. This module has been imported by another
                                          # module that wants to make use of the functions,
                                          # classes and other useful bits it has defined.
                                          

      類(lèi)型

      type() 函數(shù)有助于我們確定對(duì)象是字符串還是整數(shù),或是其它類(lèi)型的對(duì)象。它通過(guò)返回類(lèi)型對(duì)象來(lái)做到這一點(diǎn),可以將這個(gè)類(lèi)型對(duì)象與 types 模塊中定義的類(lèi)型相比較:



      清單 29. 我是您的類(lèi)型嗎?
      >>> import types
                                          >>> print types.__doc__
                                          Define names for all type symbols known in the standard interpreter.
                                          Types that are part of optional modules (e.g. array) are not listed.
                                          >>> dir(types)
                                          [‘BufferType‘, ‘BuiltinFunctionType‘, ‘BuiltinMethodType‘, ‘ClassType‘,
                                          ‘CodeType‘, ‘ComplexType‘, ‘DictProxyType‘, ‘DictType‘, ‘DictionaryType‘,
                                          ‘EllipsisType‘, ‘FileType‘, ‘FloatType‘, ‘FrameType‘, ‘FunctionType‘,
                                          ‘GeneratorType‘, ‘InstanceType‘, ‘IntType‘, ‘LambdaType‘, ‘ListType‘,
                                          ‘LongType‘, ‘MethodType‘, ‘ModuleType‘, ‘NoneType‘, ‘ObjectType‘, ‘SliceType‘,
                                          ‘StringType‘, ‘StringTypes‘, ‘TracebackType‘, ‘TupleType‘, ‘TypeType‘,
                                          ‘UnboundMethodType‘, ‘UnicodeType‘, ‘XRangeType‘, ‘__builtins__‘, ‘__doc__‘,
                                          ‘__file__‘, ‘__name__‘]
                                          >>> s = ‘a(chǎn) sample string‘
                                          >>> type(s)
                                          <type ‘str‘>
                                          >>> if type(s) is types.StringType: print "s is a string"
                                          ...
                                          s is a string
                                          >>> type(42)
                                          <type ‘int‘>
                                          >>> type([])
                                          <type ‘list‘>
                                          >>> type({})
                                          <type ‘dict‘>
                                          >>> type(dir)
                                          <type ‘builtin_function_or_method‘>
                                          

      標(biāo)識(shí)

      先前我們說(shuō)過(guò),每個(gè)對(duì)象都有標(biāo)識(shí)、類(lèi)型和值。值得注意的是,可能有多個(gè)變量引用同一對(duì)象,同樣地,變量可以引用看起來(lái)相似(有相同的類(lèi)型和值),但擁有截然不同標(biāo)識(shí)的多個(gè)對(duì)象。當(dāng)更改對(duì)象時(shí)(如將某一項(xiàng)添加到列表),這種關(guān)于對(duì)象標(biāo)識(shí)的概念尤其重要,如在下面的示例中,blistclist 變量引用同一個(gè)列表對(duì)象。正如您在示例中所見(jiàn),id() 函數(shù)給任何給定對(duì)象返回唯一的標(biāo)識(shí)符:



      清單 30. 目的地……
      >>> print id.__doc__
                                          id(object) -> integer
                                          Return the identity of an object.  This is guaranteed to be unique among
                                          simultaneously existing objects.  (Hint: it‘s the object‘s memory address.)
                                          >>> alist = [1, 2, 3]
                                          >>> blist = [1, 2, 3]
                                          >>> clist = blist
                                          >>> clist
                                          [1, 2, 3]
                                          >>> blist
                                          [1, 2, 3]
                                          >>> alist
                                          [1, 2, 3]
                                          >>> id(alist)
                                          145381412
                                          >>> id(blist)
                                          140406428
                                          >>> id(clist)
                                          140406428
                                          >>> alist is blist    # Returns 1 if True, 0 if False
                                          0
                                          >>> blist is clist    # Ditto
                                          1
                                          >>> clist.append(4)   # Add an item to the end of the list
                                          >>> clist
                                          [1, 2, 3, 4]
                                          >>> blist             # Same, because they both point to the same object
                                          [1, 2, 3, 4]
                                          >>> alist             # This one only looked the same initially
                                          [1, 2, 3]
                                          

      屬性

      我們已經(jīng)看到對(duì)象擁有屬性,并且 dir() 函數(shù)會(huì)返回這些屬性的列表。但是,有時(shí)我們只想測(cè)試一個(gè)或多個(gè)屬性是否存在。如果對(duì)象具有我們正在考慮的屬性,那么通常希望只檢索該屬性。這個(gè)任務(wù)可以由 hasattr()getattr() 函數(shù)來(lái)完成,如本例所示:



      清單 31. 具有一個(gè)屬性;獲得一個(gè)屬性
      >>> print hasattr.__doc__
                                          hasattr(object, name) -> Boolean
                                          Return whether the object has an attribute with the given name.
                                          (This is done by calling getattr(object, name) and catching exceptions.)
                                          >>> print getattr.__doc__
                                          getattr(object, name[, default]) -> value
                                          Get a named attribute from an object; getattr(x, ‘y‘) is equivalent to x.y.
                                          When a default argument is given, it is returned when the attribute doesn‘t
                                          exist; without it, an exception is raised in that case.
                                          >>> hasattr(id, ‘__doc__‘)
                                          1
                                          >>> print getattr(id, ‘__doc__‘)
                                          id(object) -> integer
                                          Return the identity of an object.  This is guaranteed to be unique among
                                          simultaneously existing objects.  (Hint: it‘s the object‘s memory address.)
                                          

      可調(diào)用

      可以調(diào)用表示潛在行為(函數(shù)和方法)的對(duì)象??梢杂?callable() 函數(shù)測(cè)試對(duì)象的可調(diào)用性:



      清單 32. 您能為我做些事情嗎?
      >>> print callable.__doc__
                                          callable(object) -> Boolean
                                          Return whether the object is callable (i.e., some kind of function).
                                          Note that classes are callable, as are instances with a __call__() method.
                                          >>> callable(‘a(chǎn) string‘)
                                          0
                                          >>> callable(dir)
                                          1
                                          

      實(shí)例

      type() 函數(shù)提供對(duì)象的類(lèi)型時(shí),還可以使用 isinstance() 函數(shù)測(cè)試對(duì)象,以確定它是否是某個(gè)特定類(lèi)型或定制類(lèi)的實(shí)例:



      清單 33. 您是那些實(shí)例中的一個(gè)嗎?
      >>> print isinstance.__doc__
                                          isinstance(object, class-or-type-or-tuple) -> Boolean
                                          Return whether an object is an instance of a class or of a subclass thereof.
                                          With a type as second argument, return whether that is the object‘s type.
                                          The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
                                          isinstance(x, A) or isinstance(x, B) or ... (etc.).
                                          >>> isinstance(42, str)
                                          0
                                          >>> isinstance(‘a(chǎn) string‘, int)
                                          0
                                          >>> isinstance(42, int)
                                          1
                                          >>> isinstance(‘a(chǎn) string‘, str)
                                          1
                                          

      子類(lèi)

      我們先前提到過(guò),定制類(lèi)的實(shí)例從該類(lèi)繼承了屬性。在類(lèi)這一級(jí)別,可以根據(jù)一個(gè)類(lèi)來(lái)定義另一個(gè)類(lèi),同樣地,這個(gè)新類(lèi)會(huì)按照層次化的方式繼承屬性。Python 甚至支持多重繼承,多重繼承意味著可以用多個(gè)父類(lèi)來(lái)定義一個(gè)類(lèi),這個(gè)新類(lèi)繼承了多個(gè)父類(lèi)。issubclass() 函數(shù)使我們可以查看一個(gè)類(lèi)是不是繼承了另一個(gè)類(lèi):



      清單 34. 您是我母親嗎?
      >>> print issubclass.__doc__
                                          issubclass(C, B) -> Boolean
                                          Return whether class C is a subclass (i.e., a derived class) of class B.
                                          >>> class SuperHero(Person):   # SuperHero inherits from Person...
                                          ...     def intro(self):       # but with a new SuperHero intro
                                          ...         """Return an introduction."""
                                          ...         return "Hello, I‘m SuperHero %s and I‘m %s." % (self.name, self.age)
                                          ...
                                          >>> issubclass(SuperHero, Person)
                                          1
                                          >>> issubclass(Person, SuperHero)
                                          0
                                          >>>
                                          





      回頁(yè)首


      檢查時(shí)間

      讓我們將上一節(jié)中討論的幾種檢查技術(shù)結(jié)合起來(lái)。為了做到這一點(diǎn),要定義自己的函數(shù) — interrogate(),它打印有關(guān)傳遞給它的任何對(duì)象的各種信息。以下是代碼,后面是其用法的幾個(gè)示例:



      清單 35. 誰(shuí)也沒(méi)料到它
      >>> def interrogate(item):
                                          ...     """Print useful information about item."""
                                          ...     if hasattr(item, ‘__name__‘):
                                          ...         print "NAME:    ", item.__name__
                                          ...     if hasattr(item, ‘__class__‘):
                                          ...         print "CLASS:   ", item.__class__.__name__
                                          ...     print "ID:      ", id(item)
                                          ...     print "TYPE:    ", type(item)
                                          ...     print "VALUE:   ", repr(item)
                                          ...     print "CALLABLE:",
                                          ...     if callable(item):
                                          ...         print "Yes"
                                          ...     else:
                                          ...         print "No"
                                          ...     if hasattr(item, ‘__doc__‘):
                                          ...         doc = getattr(item, ‘__doc__‘)
                                          ... 	doc = doc.strip()   # Remove leading/trailing whitespace.
                                          ... 	firstline = doc.split(‘\n‘)[0]
                                          ... 	print "DOC:     ", firstline
                                          ...
                                          >>> interrogate(‘a(chǎn) string‘)     # String object
                                          CLASS:    str
                                          ID:       141462040
                                          TYPE:     <type ‘str‘>
                                          VALUE:    ‘a(chǎn) string‘
                                          CALLABLE: No
                                          DOC:      str(object) -> string
                                          >>> interrogate(42)             # Integer object
                                          CLASS:    int
                                          ID:       135447416
                                          TYPE:     <type ‘int‘>
                                          VALUE:    42
                                          CALLABLE: No
                                          DOC:      int(x[, base]) -> integer
                                          >>> interrogate(interrogate)    # User-defined function object
                                          NAME:     interrogate
                                          CLASS:    function
                                          ID:       141444892
                                          TYPE:     <type ‘function‘>
                                          VALUE:    <function interrogate at 0x86e471c>
                                          CALLABLE: Yes
                                          DOC:      Print useful information about item.
                                          

      正如您在最后一個(gè)示例中所看到的,interrogate() 函數(shù)甚至可以應(yīng)用于它本身。您沒(méi)有再比它更具“自省性”的工具了。





      回頁(yè)首


      結(jié)束語(yǔ)

      誰(shuí)知道自省可以變得這么簡(jiǎn)單而又如此有價(jià)值?可是,我在結(jié)束時(shí)必須提出警告:不要將自省的結(jié)果誤認(rèn)為是萬(wàn)能的。有經(jīng)驗(yàn)的 Python 程序員知道:他們不知道的東西總是比已知的更多,因此根本不可能是萬(wàn)能的。編程行為產(chǎn)生的問(wèn)題多于答案。關(guān)于 Python 的唯一優(yōu)點(diǎn)(正如我們今天在本文中所見(jiàn))是它確實(shí)回答了人們的問(wèn)題。至于我本人,覺(jué)得您不必因?yàn)槲規(guī)椭私饬诉@些 Python 必須提供的內(nèi)容而酬謝我。用 Python 編程自有回報(bào)。我從愛(ài)好 Python 的同伴處獲得的幫助也是不計(jì)報(bào)酬的。

      上一頁(yè)



      參考資料



      關(guān)于作者

      作者照片

      Patrick O‘Brien 是一位 Python 程序員、顧問(wèn)和培訓(xùn)人員。他創(chuàng)建了 PyCrust,并且還是 PythonCard 項(xiàng)目的開(kāi)發(fā)人員。他最近帶領(lǐng) PyPerSyst 團(tuán)隊(duì)將 Prevayler 移植到了 Python,并且繼續(xù)引領(lǐng)著這個(gè)項(xiàng)目向新的令人感興趣的領(lǐng)域前進(jìn)。可以在 Orbtech 網(wǎng)站了解更多有關(guān)作者和他工作方面的情況,或者可以通過(guò) pobrien@ 與他聯(lián)系。



        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多