使用with
在对文件进行写入操作之后,一定要牢记一个事情:file.close()
,这个操作千万不要忘记,忘记了怎么办,那就补上吧,也没有什么天塌地陷的后果。
有另外一种方法,能够不用这么让人揪心,实现安全地关闭文件。
>>> with open("130.txt","a") as f:
... f.write("
This is about 'with...as...'")
...
>>> with open("130.txt","r") as f:
... print f.read()
...
learn python
http://qiwsir.github.io
qiwsir@gmail.com
hello
This is about 'with...as...'
>>>
这里就不用close()了。而且这种方法更有Python味道,或者说是更符合Pythonic的一个要求。
名称
并非所有对象都有名称,但那些有名称的对象都将名称存储在其 __name__
属性中。注:名称是从对象而不是引用该对象的变量中派生的。
>>> dir() #dir()函数
['__builtins__', '__doc__', '__name__', '__package__', 'keyword', 'math']
>>> directory = dir #新变量
>>> directory() #跟dir()一样的结果
['__builtins__', '__doc__', '__name__', '__package__', 'directory', 'keyword', 'math']
>>> dir.__name__ #dir()的名字
'dir'
>>> directory.__name__
'dir'
>>> __name__ #这是不一样的
'__main__'
模块拥有名称,Python 解释器本身被认为是顶级模块或主模块。当以交互的方式运行 Python 时,局部__name__
变量被赋予值 '__main__'
。同样地,当从命令行执行 Python 模块,而不是将其导入另一个模块时,其 __name__
属性被赋予值 '__main__'
,而不是该模块的实际名称。这样,模块可以查看其自身的 __name__
值来自行确定它们自己正被如何使用,是作为另一个程序的支持,还是作为从命令行执行的主应用程序。因此,下面这条惯用的语句在 Python 模块中是很常见的:
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.
dir()
尽管查找和导入模块相对容易,但要记住每个模块包含什么却不是这么简单。你或许并不希望总是必须查看源代码来找出答案。幸运的是,Python 提供了一种方法,可以使用内置的 dir() 函数来检查模块(以及其它对象)的内容。
其实,这个东西我们已经一直在使用。
dir() 函数可能是 Python 自省机制中最著名的部分了。它返回传递给它的任何对象的属性名称经过排序的列表。如果不指定对象,则 dir() 返回当前作用域中(这里冒出来一个新名词:“作用域”,暂且不用管它,后面会详解,你就姑且理解为某个范围吧)的名称。让我们将 dir() 函数应用于 keyword 模块,并观察它揭示了什么:
>>> import keyword
>>> dir(keyword)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'iskeyword', 'kwlist', 'main']
如果不带任何参数,则 dir() 返回当前作用域中的名称。请注意,因为我们先前导入了 keyword ,所以它们出现在列表中。导入模块将把该模块的名称添加到当前作用域:
>>> dir()
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'keyword']
>>> import math
>>> dir()
['GFileDescriptorBased', 'GInitiallyUnowned', 'GPollableInputStream', 'GPollableOutputStream', '__builtins__', '__doc__', '__name__', '__package__', 'keyword', 'math']
dir() 函数是内置函数,这意味着我们不必为了使用该函数而导入模块。不必做任何操作,Python就可识别内置函数。
再观察,看到调用 dir() 后返回了这个名称 __builtins__
。也许此处有连接。让我们在 Python 提示符下输入名称 __builtins__
,并观察 Python 是否会告诉我们关于它的任何有趣的事情:
>>> __builtins__
<module '__builtin__' (built-in)>
因此 __builtins__
看起来象是当前作用域中绑定到名为 __builtin__
的模块对象的名称。(因为模块不是只有多个单一值的简单对象,所以 Python 改在尖括号中显示关于模块的信息。)
注:如果您在磁盘上寻找 __builtin__.py
文件,将空手而归。这个特殊的模块对象是 Python 解释器凭空创建的,因为它包含着解释器始终可用的项。尽管看不到物理文件,但我们仍可以将 dir() 函数应用于这个对象,以观察所有内置函数、错误对象以及它所包含的几个杂项属性。
>>> 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() 函数适用于所有对象类型,包括字符串、整数、列表、元组、字典、函数、定制类、类实例和类方法(不理解的对象类型,会在随后的教程中讲解)。例如将 dir() 应用于字符串对象,如您所见,即使简单的 Python 字符串也有许多属性(这是前面已经知道的了,权当复习)
>>> 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']
读者可以尝试一下其它的对象类型,观察返回结果,如:dir(42)
,dir([])
,dir(())
,dir({}),
dir(dir)`。
文档字符串
在许多 dir() 示例中,您可能会注意到的一个属性是 __doc__
属性。这个属性是一个字符串,它包含了描述对象的注释。Python 称之为文档字符串或docstring(这个内容,会在下一部分中讲解如何自定义设置)。
如果模块、类、方法或函数定义的第一条语句是字符串,那么该字符串会作为对象的 __doc__
属性与该对象关联起来。例如,看一下str类型对象的文档字符串。因为文档字符串通常包含嵌入的换行
,我们将使用 Python 的 print 语句,以便输出更易于阅读:
>>> 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.