使用glob模块能够用通配符的方式搜索某个目录下的特定文件,返回结果是一个list html
import glob flist=glob.glob('*.jpeg')
使用os.getcwd()能够获得当前目录,若是想切换到其余目录,可使用os.chdir('str/to/path'),若是想执行Shell脚本,可使用os.system('mkdir newfolder')。 java
对于平常文件和目录的管理, shutil模块提供了更便捷、更高层次的接口 node
import shutil shutil.copyfile('data.db', 'archive.db') shutil.move('/build/executables', 'installdir')
使用PyCharm中,在一个Project中新建一个Directory和新建一个Package以后,IDE都会建立对应的目录,并添加默认的__init__.py文件,可是,二者仍是不同的。 若是在它们的目录下各新建一个python脚本测试输出os.getcwd(),若是是在Directory中获得的是Project的根目录’/Users/hujiawei/PycharmProjects/leetcodeoj’;若是是在Package中获得的是Package的根目录,如’/Users/hujiawei/PycharmProjects/leetcodeoj/pypackage’。 python
若是要在代码中添加中文注释的话,最好在文档开头加上下面的编码声明语句。关于Python中的字符串编码可见廖雪峰的python教程。若代码打算用在国际化的环境中, 那么不要使用奇特的编码。Python 默认的 UTF-8, 或者甚至是简单的 ASCII 在任何状况下工做得最好。一样地,若是代码的读者或维护者只有很小的几率使用不一样的语言,那么不要在标识符里使用非 ASCII 字符。 git
# coding=utf-8 或者 # -*- coding: utf-8 -*-
摘自廖雪峰的python教程 github
在Python中,变量名相似__xxx__的,也就是以双下划线开头,而且以双下划线结尾的,是特殊变量,特殊变量是能够直接访问的,不是private变量,因此,不能用__name__、__score__这样的变量名。 算法
有些时候,你会看到以一个下划线开头的实例变量名(两个下划线开头的也同样算,其实任何如下划线开头的都算),好比_name,这样的实例变量外部是能够访问的,可是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我能够被访问,可是,请把我视为私有变量,不要随意访问”。 spring
双下划线开头的实例变量是否是必定不能从外部访问呢?其实也不是。不能直接访问__name是由于Python解释器对外把__name变量改为了_Student__name,因此,仍然能够经过_Student__name来访问__name变量。可是强烈建议你不要这么干,由于不一样版本的Python解释器可能会把__name改为不一样的变量名。 编程
总的来讲就是,Python自己没有任何机制阻止你干坏事,一切全靠自觉。 app
上面说的有点绕,下面我写了两个python脚本,你们能够对照看下哪些可以访问,哪些不能,不能的状况下如何操做变得能够访问(注释后面的yes和no表示能不能被访问)。
也就是说,默认呢,以一个下划线开始(不论结尾有没有下划线)的变量在外部都是能够直接访问的,可是不推荐这么作;以两个下划线开始和两个下划线结束的变量属于特殊变量,能够直接访问;而以两个下划线开始且结尾不是两个下划线(能够没有也能够有一个下划线)的变量属于私有变量,不能直接访问,虽然能够经过其余方式访问,但最好不要在外部访问。
文件 APythonTestA.py
# coding=utf-8 class ListNode: _class_field10 = 'node class field 1-0' _class_field11_ = 'node class field 1-1' _class_field12__ = 'node class field 1-2' __class_field20 = 'node class field 2-0' __class_field21_ = 'node class field 2-1' __class_field22__ = 'node class field 2-2' def __init__(self, x): self.val = x self.next = None _class_field10 = 'node class field 1-0' _class_field11_ = 'node class field 1-1' _class_field12__ = 'node class field 1-2' __class_field20 = 'node class field 2-0' __class_field21_ = 'node class field 2-1' __class_field22__ = 'node class field 2-2'
文件 APythonTestB.py
# coding=utf-8 __author__ = 'hujiawei' __doc__ = 'for python test 2' import APythonTestA if __name__ == '__main__': print(dir(APythonTestA.ListNode)) node = APythonTestA.ListNode(4) # print(node._ListNode__class_field20) #yes print(node._class_field10) #yes print(node._class_field11_) #yes print(node._class_field12__) #yes # print(node.__class_field20) #no print(node._ListNode__class_field20)#yes # print(node.__class_field21_) #no print(node._ListNode__class_field21_)#yes print(node.__class_field22__) #yes print(dir(APythonTestA)) print(APythonTestA._class_field10) #yes print(APythonTestA._class_field11_) #yes print(APythonTestA._class_field12__) #yes print(APythonTestA.__class_field20) #yes print(APythonTestA.__class_field21_) #yes print(APythonTestA.__class_field22__) #yes # ['_ListNode__class_field20', '_ListNode__class_field21_', '__class_field22__', '__doc__', '__init__', '__module__', '_class_field10', '_class_field11_', '_class_field12__'] # node class field 1-0 # node class field 1-1 # node class field 1-2 # node class field 2-0 # node class field 2-1 # node class field 2-2 # ['ListNode', '__builtins__', '__class_field20', '__class_field21_', '__class_field22__', '__doc__', '__file__', '__name__', '__package__', '_class_field10', '_class_field11_', '_class_field12__'] # node class field 1-0 # node class field 1-1 # node class field 1-2 # node class field 2-0 # node class field 2-1 # node class field 2-2
Python的函数具备很是灵活的参数形态,既能够实现简单的调用,又能够传入很是复杂的参数。 默认参数必定要用不可变对象,若是是可变对象,运行会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既能够直接传入:func(1, 2, 3),又能够先组装list或tuple,再经过*args传入:func(*(1, 2, 3));
关键字参数既能够直接传入:func(a=1, b=2),又能够先组装dict,再经过**kw传入:func(**{'a': 1, 'b': 2})。
使用*args和**kw是Python的习惯写法,固然也能够用其余参数名,但最好使用习惯用法。
切片,迭代,列表生成式,生成器
除非特殊的缘由,应该常常在代码中使用生成器表达式。但除非是面对很是大的列表,不然是不会看出明显区别的。
使用生成器获得当前目录及其子目录中的全部文件的代码,下面代码来自伯乐在线-python高级编程技巧
import os def tree(top): #path,folder list,file list for path, names, fnames in os.walk(top): for fname in fnames: yield os.path.join(path, fname) for name in tree(os.getcwd()): print name
另外一个使用生成器的代码示例:
num = [1, 4, -5, 10, -7, 2, 3, -1] def square_generator(optional_parameter): return (x ** 2 for x in num if x > optional_parameter) print square_generator(0) # <generator object <genexpr> at 0x004E6418> # Option I for k in square_generator(0): print k # 1, 16, 100, 4, 9 # Option II g = list(square_generator(0)) print g # [1, 16, 100, 4, 9]
参见廖雪峰的python教程,讲解得很好
高阶函数(使用函数做为参数或者返回一个函数的函数称为高阶函数),匿名函数(lambda),装饰器(decorator)和偏函数
用来测试一个函数花费的运行时间的装饰器,固然你也可使用其余的方式,好比Timer来获得运行时间。下面代码来自伯乐在线-python高级编程技巧
def timethis(func): ''' Decorator that reports the execution time. ''' @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end-start) return result return wrapper @timethis def countdown(n): while n > 0: n -= 1
其中代码
@timethis def countdown(n):
就至关于:
def countdown(n): ... countdown = timethis(countdown)
装饰器除了可使用函数实现,也可使用类来实现。
对装饰器的类实现的惟一要求是它必须能如函数通常使用,也就是说它必须是可调用的。因此,若是想这么作这个类必须实现__call__方法。
class decorator(object): def __init__(self, f): print("inside decorator.__init__()") f() # Prove that function definition has completed def __call__(self): print("inside decorator.__call__()") @decorator def function(): print("inside function()") print("Finished decorating function()") function() # inside decorator.__init__() # inside function() # Finished decorating function() # inside decorator.__call__()
语法糖@decorator至关于function=decorator(function),在此调用decorator的__init__打印“inside decorator.__init__()”
随后执行f()打印“inside function()”
随后执行“print(“Finished decorating function()”)”
最后再调用function函数时,因为使用装饰器包装,所以执行decorator的__call__打印 “inside decorator.__call__()”。
==个人批注:我以为上面代码不是通常的使用方式,实际装饰器类应该是在__init__方法中设置好本身内部的函数f,而后在方法__call__中调用函数f,并包含一些其余的方法调用,大概以下:
class decorator(object): def __init__(self, f): print("inside decorator.__init__()") # f() # Prove that function definition has completed self.f=f def __call__(self): print("inside decorator.__call__() begin") self.f() print("inside decorator.__call__() end") @decorator def function(): print("inside function()") print("Finished decorating function()") function() # inside decorator.__init__() # Finished decorating function() # inside decorator.__call__() begin # inside function() # inside decorator.__call__() end
在提供一个装饰器的例子,实现自顶向下的带备忘录的DP算法来解决斐波那契数列求值,来源于Python Algorithms- Mastering Basic Algorithms in the Python Language
from functools import wraps def memo(func): cache={} @wraps(func) def wrap(*args): if args not in cache: cache[args]=func(*args) return cache[args] return wrap @memo def fib(i): if i<2: return 1 return fib(i-1)+fib(i-2) print(fib(100))
python函数传递的是对象的引用值,非传值或传引用。可是若是对象是不可变的,感受和c语言中传值差很少。若是对象是可变的,感受和c语言中传引用差很少。
运行下面的代码就清楚了
def foo(a): print "传来是对象的引用对象地址为{0}".format(id(a)) a = 3 #形式参数a是局部变量,a从新绑定到3这个对象。 print "变量a新引用对象地址为{0}".format(id(a)) # print a x = 5 print "全局变量x引用的对象地址为{0}".format(id(x)) foo(x) print "变量x新引用对象地址为{0}".format(id(x)) print x #因为函数内部a绑定到新的对象,也就修改不了全局变量x引用的对象5 # 全局变量x引用的对象地址为140462615725816 # 传来是对象的引用对象地址为140462615725816 # 变量a新引用对象地址为140462615725864 # 变量x新引用对象地址为140462615725816 # 5 def foo(a): """在函数内部直接修改了同一个引用指向的对象。 也就修改了实际参数传来的引用值指向的对象。 """ a.append("can change object") return a lst = [1,2,3] print foo(lst) print lst #[1, 2, 3, 'can change object'] #[1, 2, 3, 'can change object'] def foo(a): """实际参数传来一个对象[1,2,3]的引用,当时形式参数 (局部变量a从新引用到新的对象,也就是说保存了新的对象) 固然不能修改原来的对象了。 """ a = ["python","java"] return a lst = [1,2,3] for item in foo(lst): print item print lst # python # java # coding=utf-8 # 测试utf-8编码 import sys reload(sys) sys.setdefaultencoding('utf-8') list_a = [] def a(): # list_a = [1] ## 语句1 [] list_a.append(1) ## 语句2 [1] a() print list_a
http://hujiaweibujidao.github.io/blog/2014/05/10/python-tips1/
Python Algorithms - Dynamic Programming
http://hujiaweibujidao.github.io/blog/2014/05/08/python-algorithms-dynamic-programming/