Andy Niu Help
1.0.0.0
|
变量 | |
Python导入导出 | |
理解import | |
Python_Swap | |
Python的设计哲学 | |
Python命令行查看帮助文档 | |
查看帮助信息 | |
pyc文件和pyo文件 | |
__name__ | |
元祖不可变 | |
详细描述
变量说明
__name__ |
1、考虑下面的需求,写了一个模块,里面有测试代码,运行的时候,执行测试代码。 但是,当这个模块被import的时候,我们不期望执行测试代码,怎么办? 2、这就需要使用,__name__,如下: if __name__ == '__main__': print "this is animal" raw_input() __name__可以认为是条件编译,当运行的时候,取值为'__main__' 被import的时候,取值为 模块名称 3、测试如下: class Animal(object): name='' age=0 print __name__ if __name__ == '__main__': print "this is animal" raw_input()
pyc文件和pyo文件 |
1、pyc文件,是python编译后的字节码(bytecode)文件。只要你运行了py文件,python编译器就会自动生成 一个对应的pyc字节码文件。这个pyc字节码文件,经过python解释器,会生成机器码运行。 (这也是为什么pyc文件可以跨平台部署,类似于java的跨平台,java中JVM运行的字节码文件)。 下次调用直接调用pyc,而不调用py文件。直到你这个py文件有改变。 python解释器会检查pyc文件中的生成时间,对比py文件的修改时间,如果py更新,那么就生成新的pyc。 2、pyo文件,是python编译优化后的字节码文件。pyo文件在大小上,一般小于等于pyc文件。 如果想得到某个py文件的pyo文件,可以这样: python -O -m py_compile xxxx.py python文档是这样描述的:这个优化没有多大作用,只是移除了断言。 3、至于速度,运行几乎一样,加载pyc和pyo稍占优势。
Python_Swap |
1、在C++中有值语义和引用语义,而Python中只有引用的语义。 2、示例如下: >>> a=1 >>> a 1 >>> id(a) 19310280 >>> b=a >>> b 1 >>> b=2 >>> b 2 >>> id(2) 19310268 解释如下: b=a,b和a指向同一个对象,对象的引用计数为2, b=2,修改b的指向,指向2,a的引用计数减1,为1 3、因此,对于swap的实现, def swap(a,b): t=a a=b b=t return 是错误的,这里这是修改了形参的指向,实参的指向,并没有改变。解决办法如下: def swap(a,b): return b,a 调用如下: a,b=swap(a,b)
Python命令行查看帮助文档 |
1、使用dir,列出所有的属性 >>> dir(str) >>> dir(str.split) 在python中任何东西都是对象,str.split是个方法,也是个对象 2、使用__doc__ 查看对象的描述 >>> print(str.__doc__) >>> print(str.split.__doc__) 3、使用help,返回使用说明 >>> help(str) >>> help(str.split)
Python导入导出 |
1、import xxx,导入某个模块。如下: >>> import time >>> print time.strftime('%Y-%m-%d %H:%M:%S') 2015-08-21 21:59:43 注:time.strftime 中的time是模块名,也就是文件名 2、上面还要写上 print time.strftime('%Y-%m-%d %H:%M:%S'),如果想省略time,可以使用: >>> from time import * >>> print strftime('%Y-%m-%d %H:%M:%S') 2015-08-21 22:02:32 3、使用from time import *,导致一个问题,就是从模块time导入太多的东西,会污染当前的名称空间。怎么解决? 只导入自己需要的东西,要使用方法strftime,就只导入方法strftime,如下: >>> from time import strftime >>> print strftime('%Y-%m-%d %H:%M:%S') 2015-09-01 08:48:24
Python的设计哲学 |
Python的设计哲学是优雅、明确、简单。 Perl语言,同一件事,提供多种方法来做。 而Python,同一件事最好只有一种方法来做。 Python这样做有什么好处? 这会减轻程序员的心智负担,举例来说,C++中的string,计算字符串长度,有两种方法length()和size() 程序员就会想这两种方法有什么区别。孟岩在博客中写道,相对于C,C++增加了程序员的心智负担。这个 影响很严重,语言提供的相似接口越多,参数越多,特性越多,程序员写程序的时候越没有自信,总是在想 :这样固然可以work,但恐怕还有更好的方案吧?会是什么呢? 使用模板参数,抽象出一个基类,使用策略模式 ,使用编译时多态,还是运行时多态,内存谁来回收呢?使用智能指针,各种智能指针有什么区别呢?哎呀不行行不行了, 太复杂了,还是能够work就算了。而C程序员没有这些负担,C语言提供的够用,想要啥就写啥没有什么事先不了。 语言新特性也有同样的问题: 1、新特性加重了编译器的编译负担。 2、新特性加重了运行时的运行负担。 3、新特性加重了程序员的心智负担。
元祖不可变 |
1、Python彻底分离了指针和内容,每次修改内容,都相当于,修改指针指向另一块内容。 2、需要注意的是,Python使用了共享内存,如果内容相同,指向同一块内存。如下: >>> a='hello' >>> b='hello' >>> id(a) 43861376 >>> id(b) 43861376 可以这样理解,a='hello' 分配一块内存,内容为"hello",a指向这块内存。 b='hello' 先检查有没有这样的一块内存,内容为"hello",刚好找到,地址返回给b 从内容到地址,可以使用哈希表,内容映射到地址。每次修改内容,对新的内容哈希,看看是否存在一个地址,保存的内容刚好为 新的内容,如果存在,直接返回地址。如果不存在,new出一个,返回地址。 C++静态存储区也是同样的道理。 3、查看下面的情况: >>> a=123 >>> b=a >>> b=456 >>> a 123 >>> b 456 这和C++中的写时拷贝(copy-on-write),道理一样。b=a是指针语义,只复制指针。 b=456修改b的时候,b指向新的内容,但是a的指向不变,这个时候是值语义。 4、元祖的元素也是指针,元祖的不可变指的是,元素不能指向其他地方,从C++角度理解,就是const指针,不能修改指向。 但是,元祖本身是可以变的,可以指向其他的内容。如下: >>> aTuple=(1,2) >>> aTuple[0]=5 // 元素不能修改指向 Traceback (most recent call last): File "<pyshell#34>", line 1, in <module> aTuple[0]=5 TypeError: 'tuple' object does not support item assignment >>> aTuple=(3,4) // 元祖本身可以修改指向 >>> aTuple (3, 4) 5、list与tuple之间的转化,使用list方法和tuple方法,返回一个list或者tuple,如下: >>> aList=list(aTuple) >>> aList [3, 4] >>> aList[1]=100 >>> aList [3, 100] >>> bTuple=tuple(aList) >>> bTuple (3, 100)
查看帮助信息 |
1、help >>> help(Animal) Help on class Animal in module animal: class Animal(__builtin__.object) | Methods defined here: | | say(self) | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | age = 0 | | name = '' 2、dir >>> dir(Animal) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'say'] 3、查询父类 >>> Animal.__base__ <type 'object'> 4、是否有某个属性 >>> hasattr(Animal,'name') True 5、方法的参数 >>> inspect.getargspec(Animal.say) ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)
理解import |
1、import一个模块,如下: >>> import c >>> c1=C(); Traceback (most recent call last): File "<pyshell#1>", line 1, in <module> c1=C(); NameError: name 'C' is not defined >>> c1=c.C(); >>> c1.say(); I am c 需要注意的是,import一个模块,使用模块中的对象时,需要在对象前面加上模块名称,也就是文件名。 2、怎么解决上面的问题? 使用import,从模块中import对象,如下: >>> from c import C >>> c1=C(); >>> c1.say(); I am c 这种情况下,可以直接使用对象。 3、如何import子目录中的模块? 考虑当前有 ./a/a.py, 如何import a.py 在./a目录创建一个空的文件 __init__.py 即可 >>> import a.a Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> import a.a ImportError: No module named a.a >>> import a.a 4、如何引用父目录中模块? 考虑当前目录为./a/ 父目录下有./b/b.py, 如何import a.py 使用 sys增加搜索路径 >>> import sys; >>> sys.path.append('../b'); >>> import b; 对于import子目录中的模块,也可以使用这种方式。
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.