自省

2018-02-24 15:48 更新

特別說(shuō)明,這一講的內(nèi)容不是我寫(xiě)的,是我從《Python自省指南》抄錄過(guò)來(lái)的,當(dāng)然,為了適合本教程,我在某些地方做了修改或者重寫(xiě)。

什么是自???

在日常生活中,自?。╥ntrospection)是一種自我檢查行為。自省是指對(duì)某人自身思想、情緒、動(dòng)機(jī)和行為的檢查。偉大的哲學(xué)家蘇格拉底將生命中的大部分時(shí)間用于自我檢查,并鼓勵(lì)他的雅典朋友們也這樣做。他甚至對(duì)自己作出了這樣的要求:“未經(jīng)自省的生命不值得存在?!睙o(wú)獨(dú)有偶,在中國(guó)《論語(yǔ)》中,也有這樣的名言:“吾日三省吾身”。顯然,自省對(duì)個(gè)人成長(zhǎng)多么重要呀。

在計(jì)算機(jī)編程中,自省是指這種能力:檢查某些事物以確定它是什么、它知道什么以及它能做什么。自省向程序員提供了極大的靈活性和控制力。一旦您使用了支持自省的編程語(yǔ)言,就會(huì)產(chǎn)生類(lèi)似這樣的感覺(jué):“未經(jīng)檢查的對(duì)象不值得實(shí)例化?!?/p>

整個(gè) Python 語(yǔ)言對(duì)自省提供了深入而廣泛的支持。實(shí)際上,很難想象假如 Python語(yǔ)言沒(méi)有其自省特性是什么樣子。

學(xué)完這節(jié),你就能夠輕松洞察到 Python 對(duì)象的“靈魂”。

在深入研究更高級(jí)的技術(shù)之前,我們盡可能用最普通的方式來(lái)研究 Python自省。有些讀者甚至可能會(huì)爭(zhēng)論說(shuō):我們開(kāi)始時(shí)所討論的特性不應(yīng)稱(chēng)之為“自省”。我們必須承認(rèn),它們是否屬于自省的范疇還有待討論。但從本節(jié)的意圖出發(fā),我們所關(guān)心的只是找出有趣問(wèn)題的答案。

現(xiàn)在讓我們以交互方式使用 Python 來(lái)開(kāi)始研究。這是前面已經(jīng)在使用的一種方式。

聯(lián)機(jī)幫助

在交互模式下,用help向python請(qǐng)求幫助。

>>> help()

Welcome to Python 2.7!  This is the online help utility.

If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/2.7/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics".  Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".

help> 

這時(shí)候就進(jìn)入了聯(lián)機(jī)幫助狀態(tài),根據(jù)提示輸入keywords

help> keywords

Here is a list of the Python keywords.  Enter any keyword to get more help.

and                 elif                if                  print
as                  else                import              raise
assert              except              in                  return
break               exec                is                  try
class               finally             lambda              while
continue            for                 not                 with
def                 from                or                  yield
del                 global              pass                

現(xiàn)在顯示出了python關(guān)鍵詞的列表。依照說(shuō)明亦步亦趨,輸入每個(gè)關(guān)鍵詞,就能看到那個(gè)關(guān)鍵詞的相關(guān)文檔。這里就不展示輸入的結(jié)果了。讀者可以自行嘗試。要記住,如果從文檔說(shuō)明界面返回到幫助界面,需要按q鍵。

這樣,我們能夠得到聯(lián)機(jī)幫助。從聯(lián)機(jī)幫助狀態(tài)退回到python的交互模式,使用quit命令。

help> quit

You are now leaving help and returning to the Python interpreter.
If you want to ask for help on a particular object directly from the
interpreter, you can type "help(object)".  Executing "help('string')"
has the same effect as typing a particular string at the help> prompt.
>>> 

聯(lián)機(jī)幫助實(shí)用程序會(huì)顯示關(guān)于各種主題或特定對(duì)象的信息。

幫助實(shí)用程序很有用,并確實(shí)利用了 Python的自省能力。但僅僅使用幫助不會(huì)揭示幫助是如何獲得其信息的。而且,因?yàn)槲覀兊哪康氖墙沂?Python 自省的所有秘密,所以我們必須迅速地跳出對(duì)幫助實(shí)用程序的討論。

在結(jié)束關(guān)于幫助的討論之前,讓我們用它來(lái)獲得一個(gè)可用模塊的列表。

模塊只是包含 Python 代碼的文本文件,其名稱(chēng)后綴是 .py ,關(guān)于模塊,本教程會(huì)在后面有專(zhuān)門(mén)的講解。如果在 Python 提示符下輸入 help('modules') ,或在 help 提示符下輸入 modules,則會(huì)看到一長(zhǎng)列可用模塊,類(lèi)似于下面所示的部分列表。自己嘗試它以觀(guān)察您的系統(tǒng)中有哪些可用模塊,并了解為什么會(huì)認(rèn)為 Python 是“自帶電池”的(自帶電池,這是一個(gè)比喻,就是說(shuō)python在被安裝時(shí),就帶了很多模塊,這些模塊是你以后開(kāi)發(fā)中會(huì)用到的,比喻成電池,好比開(kāi)發(fā)的助力工具),或者說(shuō)是python一被安裝,就已經(jīng)包含有的模塊,不用我們費(fèi)力再安裝了。

>>> help("modules")

Please wait a moment while I gather a list of all available modules...
ANSI                _threading_local    gnomekeyring        repr
BaseHTTPServer      _warnings           gobject             requests
MySQLdb             chardet             lsb_release         sre_parse
......(此處省略一些)
PyQt4               codeop              markupbase          stringprep
Queue               collections         marshal             strop
ScrolledText        colorama            math                struct
......(省略其它的模塊)
Enter any module name to get more help.  Or, type "modules spam" to search
for modules whose descriptions contain the word "spam".

因?yàn)樘?,無(wú)法全部顯示。你可以子線(xiàn)觀(guān)察一下,是不是有我們前面已經(jīng)用過(guò)的那個(gè)mathrandom模塊呢?

如果是在python交互模式>>>下,比如要得到有關(guān)math模塊的更多幫助,可以輸入>>> help("math"),如果是在幫助模式help>下,直接輸入>math就能得到關(guān)于math模塊的詳細(xì)信息。簡(jiǎn)直太貼心了。

dir()

盡管查找和導(dǎo)入模塊相對(duì)容易,但要記住每個(gè)模塊包含什么卻不是這么簡(jiǎn)單。你或許并不希望總是必須查看源代碼來(lái)找出答案。幸運(yùn)的是,Python 提供了一種方法,可以使用內(nèi)置的 dir() 函數(shù)來(lái)檢查模塊(以及其它對(duì)象)的內(nèi)容。

其實(shí),這個(gè)東西我們已經(jīng)一直在使用。

dir() 函數(shù)可能是 Python 自省機(jī)制中最著名的部分了。它返回傳遞給它的任何對(duì)象的屬性名稱(chēng)經(jīng)過(guò)排序的列表。如果不指定對(duì)象,則 dir() 返回當(dāng)前作用域中(這里冒出來(lái)一個(gè)新名詞:“作用域”,暫且不用管它,后面會(huì)詳解,你就姑且理解為某個(gè)范圍吧)的名稱(chēng)。讓我們將 dir() 函數(shù)應(yīng)用于 keyword 模塊,并觀(guān)察它揭示了什么:

>>> import keyword
>>> dir(keyword)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'iskeyword', 'kwlist', 'main']

如果不帶任何參數(shù),則 dir() 返回當(dāng)前作用域中的名稱(chēng)。請(qǐng)注意,因?yàn)槲覀兿惹皩?dǎo)入了 keyword ,所以它們出現(xiàn)在列表中。導(dǎo)入模塊將把該模塊的名稱(chēng)添加到當(dāng)前作用域:

>>> dir()
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'keyword']
>>> import math
>>> dir()
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'keyword', 'math']

dir() 函數(shù)是內(nèi)置函數(shù),這意味著我們不必為了使用該函數(shù)而導(dǎo)入模塊。不必做任何操作,Python就可識(shí)別內(nèi)置函數(shù)。

再觀(guān)察,看到調(diào)用 dir() 后返回了這個(gè)名稱(chēng)?__builtins__?。也許此處有連接。讓我們?cè)?Python 提示符下輸入名稱(chēng)__builtins__?,并觀(guān)察 Python 是否會(huì)告訴我們關(guān)于它的任何有趣的事情:

>>> __builtins__
<module '__builtin__' (built-in)>

因此?__builtins__?看起來(lái)象是當(dāng)前作用域中綁定到名為?__builtin__?的模塊對(duì)象的名稱(chēng)。(因?yàn)槟K不是只有多個(gè)單一值的簡(jiǎn)單對(duì)象,所以 Python 改在尖括號(hào)中顯示關(guān)于模塊的信息。)

注:如果您在磁盤(pán)上尋找?__builtin__.py?文件,將空手而歸。這個(gè)特殊的模塊對(duì)象是 Python 解釋器憑空創(chuàng)建的,因?yàn)樗忉屍魇冀K可用的項(xiàng)。盡管看不到物理文件,但我們?nèi)钥梢詫?dir() 函數(shù)應(yīng)用于這個(gè)對(duì)象,以觀(guān)察所有內(nèi)置函數(shù)、錯(cuò)誤對(duì)象以及它所包含的幾個(gè)雜項(xiàng)屬性。

>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'ascii', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'ngettext', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

dir() 函數(shù)適用于所有對(duì)象類(lèi)型,包括字符串、整數(shù)、列表、元組、字典、函數(shù)、定制類(lèi)、類(lèi)實(shí)例和類(lèi)方法(不理解的對(duì)象類(lèi)型,會(huì)在隨后的教程中講解)。例如將 dir() 應(yīng)用于字符串對(duì)象,如您所見(jiàn),即使簡(jiǎn)單的 Python 字符串也有許多屬性(這是前面已經(jīng)知道的了,權(quán)當(dāng)復(fù)習(xí))

>>> dir("You raise me up")
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

讀者可以嘗試一下其它的對(duì)象類(lèi)型,觀(guān)察返回結(jié)果,如:dir(42),dir([]),dir(()),dir({}),dir(dir)`。

文檔字符串

在許多 dir() 示例中,您可能會(huì)注意到的一個(gè)屬性是?__doc__?屬性。這個(gè)屬性是一個(gè)字符串,它包含了描述對(duì)象的注釋。Python 稱(chēng)之為文檔字符串或docstring(這個(gè)內(nèi)容,會(huì)在下一部分中講解如何自定義設(shè)置)。

如果模塊、類(lèi)、方法或函數(shù)定義的第一條語(yǔ)句是字符串,那么該字符串會(huì)作為對(duì)象的?__doc__?屬性與該對(duì)象關(guān)聯(lián)起來(lái)。例如,看一下str類(lèi)型對(duì)象的文檔字符串。因?yàn)槲臋n字符串通常包含嵌入的換行 \n ,我們將使用 Python 的 print 語(yǔ)句,以便輸出更易于閱讀:

>>> print str.__doc__
str(object='') -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.

檢查python對(duì)象

前面已經(jīng)好幾次提到了“對(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ì)象。

其實(shí),我總覺(jué)得把object翻譯成對(duì)象,讓人感覺(jué)很沒(méi)有具象的感覺(jué),因?yàn)樵跐h語(yǔ)里面,對(duì)象是一個(gè)很籠統(tǒng)的詞匯。另外一種翻譯,流行于臺(tái)灣,把它稱(chēng)為“物件”,倒是挺不錯(cuò)的理解。當(dāng)然,名詞就不糾纏了,關(guān)鍵是理解內(nèi)涵。關(guān)于面向?qū)ο缶幊蹋梢蚤喿x維基百科的介紹——面向?qū)ο蟪绦蛟O(shè)計(jì)——先了解大概。

類(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ù)揭示了這些屬性。

于是在計(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ì)象的情況。如希望python告訴我們:

  • 對(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ì)象的變量中派生的。

>>> dir()    #dir()函數(shù)
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'keyword', 'math']
>>> directory = dir    #新變量
>>> directory()        #跟dir()一樣的結(jié)果
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'directory', 'keyword', 'math']
>>> dir.__name__       #dir()的名字
'dir'
>>> directory.__name__
'dir'

>>> __name__          #這是不一樣的   
'__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)的:

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)型相比較:

>>> 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)
['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
>>> p = "I love Python"
>>> type(p)
<type 'str'>
>>> if type(p) is types.StringType:
...     print "p is a string"
... 
p 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í)的概念尤其重要,如在下面的示例中, blist 和 clist 變量引用同一個(gè)列表對(duì)象。正如您在示例中所見(jiàn), id() 函數(shù)給任何給定對(duì)象返回唯一的標(biāo)識(shí)符。其實(shí),這個(gè)東東我們也在前面已經(jīng)使用過(guò)了。在這里再次提出,能夠讓你理解上有提升吧。

>>> 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
>>> id(alist)
2979691052L
>>> id(blist)
2993911916L
>>> id(clist)
2993911916L
>>> alist is blist
False
>>> blist is clist
True
>>> clist.append(4)
>>> clist
[1, 2, 3, 4]
>>> blist
[1, 2, 3, 4]
>>> alist
[1, 2, 3]

如果對(duì)上面的操作還有疑惑,可以回到前面復(fù)習(xí)有關(guān)深拷貝和淺拷貝的知識(shí)。

屬性

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

>>> print hasattr.__doc__
hasattr(object, name) -> bool

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__')
True

>>> 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)用性:

>>> print callable.__doc__
callable(object) -> bool

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 string")
False
>>> callable(dir)
True

實(shí)例

這個(gè)名詞還很陌生,沒(méi)關(guān)系,先看看,混個(gè)臉熟,以后會(huì)經(jīng)常用到。

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

>>> print isinstance.__doc__
isinstance(object, class-or-type-or-tuple) -> bool

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)
False
>>> isinstance("python", str)
True

子類(lèi)

關(guān)于類(lèi)的問(wèn)題,有一個(gè)“繼承”概念,有繼承就有父子問(wèn)題,這是在現(xiàn)實(shí)生活中很正常的,在編程語(yǔ)言中也是如此。雖然這是后面要說(shuō)的,但是,為了本講內(nèi)容的完整,也姑且把這個(gè)內(nèi)容放在這里。讀者可以不看,留著以后看也行。我更建議還是閱讀一下,有個(gè)印象。

在類(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):

>>> 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

python文檔

文檔,這個(gè)詞語(yǔ)在經(jīng)常在程序員的嘴里冒出來(lái),有時(shí)候他們還經(jīng)常以文檔有沒(méi)有或者全不全為標(biāo)準(zhǔn)來(lái)衡量一個(gè)軟件項(xiàng)目是否高大上。那么,軟件中的文檔是什么呢?有什么要求呢?python文檔又是什么呢?文檔有什么用呢?

文檔很重要。獨(dú)孤九劍的劍訣、易筋經(jīng)的心法、寫(xiě)著辟邪劍譜的袈裟,這些都是文檔。連那些大牛人都要這些文檔,更何況我們呢?所以,文檔是很重要的。

文檔,說(shuō)白了就是用word(這個(gè)最多了)等(注意這里的等,把不常用的工具都等掉了,包括我編輯文本時(shí)用的vim工具)文本編寫(xiě)工具寫(xiě)成的包含文本內(nèi)容但不限于文字的文件。有點(diǎn)啰嗦,啰嗦的目的是為了嚴(yán)謹(jǐn),呵呵。最好還是來(lái)一個(gè)更讓人信服的定義,當(dāng)然是來(lái)自維基百科。

軟件文檔或者源代碼文檔是指與軟件系統(tǒng)及其軟件工程過(guò)程有關(guān)聯(lián)的文本實(shí)體。文檔的類(lèi)型包括軟件需求文檔,設(shè)計(jì)文檔,測(cè)試文檔,用戶(hù)手冊(cè)等。其中的需求文檔,設(shè)計(jì)文檔和測(cè)試文檔一般是在軟件開(kāi)發(fā)過(guò)程中由開(kāi)發(fā)者寫(xiě)就的,而用戶(hù)手冊(cè)等非過(guò)程類(lèi)文檔是由專(zhuān)門(mén)的非技術(shù)類(lèi)寫(xiě)作人員寫(xiě)就的。

早期的軟件文檔主要指的是用戶(hù)手冊(cè),根據(jù)Barker的定義,文檔是用來(lái)對(duì)軟件系統(tǒng)界面元素的設(shè)計(jì)、規(guī)劃和實(shí)現(xiàn)過(guò)程的記錄,以此來(lái)增強(qiáng)系統(tǒng)的可用性。而Forward則認(rèn)為軟件文檔是被軟件工程師之間用作溝通交流的一種方式,溝通的信息主要是有關(guān)所開(kāi)發(fā)的軟件系統(tǒng)。Parnas則強(qiáng)調(diào)文檔的權(quán)威性,他認(rèn)為文檔應(yīng)該提供對(duì)軟件系統(tǒng)的精確描述。

綜上,我們可以將軟件文檔定義為:

1.文檔是一種對(duì)軟件系統(tǒng)的書(shū)面描述; 2.文檔應(yīng)當(dāng)精確地描述軟件系統(tǒng); 3.軟件文檔是軟件工程師之間用作溝通交流的一種方式; 4.文檔的類(lèi)型有很多種,包括軟件需求文檔,設(shè)計(jì)文檔,測(cè)試文檔,用戶(hù)手冊(cè)等; 5.文檔的呈現(xiàn)方式有很多種,可以是傳統(tǒng)的書(shū)面文字形式或圖表形式,也可是動(dòng)態(tài)的網(wǎng)頁(yè)形式

那么這里說(shuō)的Python文檔指的是什么呢?一個(gè)方面就是每個(gè)學(xué)習(xí)者要學(xué)習(xí)python,python的開(kāi)發(fā)者們(他們都是大牛)給我們這些小白提供了什么東西沒(méi)有?能夠讓我們給他們這些大牛溝通,理解python中每個(gè)函數(shù)、指令等的含義和用法呢?

有。大牛就是大牛,他們準(zhǔn)備了,而且還不止一個(gè)。

真誠(chéng)的敬告所有看本教程的諸位,要想獲得編程上的升華,看文檔是必須的。文檔勝過(guò)了所有的教程和所有的老師以及所有的大牛。為什么呢?其中原因,都要等待看官看懂了之后,有了體會(huì)感悟之后才能明白。

python文檔的網(wǎng)址:https://docs.python.org/2/,這是python2.x,從這里也可以找到python3.x的文檔。

當(dāng)然,除了看官方文檔之外,自己寫(xiě)的東西也可以寫(xiě)上文檔。這個(gè)先不要著急,我們會(huì)在后續(xù)的學(xué)習(xí)中看到。

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)