## 基本数据结构(列表，元组，字典等)

### 判断一个列表为空得最佳实践

```if not a:
print "List is empty"
#不要用len(a)来判断
```

### 为什么是string.join(list)而不是list.join(string)

```my_list = ["Hello", "world"]
print "-".join(my_list)
#为什么不是 my_list.join("-") 。。。。这个....
```

### 如何合并两个列表

```listone = [1,2,3]
listtwo = [4,5,6]
#outcome we expect: mergedlist == [1, 2, 3, 4, 5, 6]
```

1.不考虑顺序（原来问题不是很明确）

```listone + listtwo
#linstone.extend(listtwo)也行，就是会修改listone
```

2.考虑顺序做些处理

```>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>> import itertools
>>> for item in itertools.chain(listone, listtwo):
...     print item
...
1
2
3
4
5
6
```

### 如何扁平一个二维数组

```l = [[1,2,3],[4,5,6], [7], [8,9]]

```

```[item for sublist in l for item in sublist]
```

itertools

```>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain(*list2d))

# python >= 2.6
>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain.from_iterable(list2d))
```

sum

```sum(l, [])
```

### 如何获取一个列表的长度

python中是不是只有这种方法可以获取长度？语法很奇怪

```arr.__len__()
```

```mylist = [1,2,3,4,5]
len(mylist)
```

### Python中如何复制一个列表

```new_list = old_list[:]
```

```new_list = list(old_list)
```

```import copy
new_list = copy.copy(old_list)
```

```import copy
new_list = copy.deepcopy(old_list)
```

```import copy

class Foo(object):
def __init__(self, val):
self.val = val

def __repr__(self):
return str(self.val)

foo = Foo(1)

a = ['foo', foo]
b = a[:]
c = list(a)
d = copy.copy(a)
e = copy.deepcopy(a)

# edit orignal list and instance
a.append('baz')
foo.val = 5

print "original: %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r" \
% (a, b, c, d, e)
```

```original: ['foo', 5, 'baz']
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]
```

```10.59 - copy.deepcopy(old_list)
10.16 - pure python Copy() method copying classes with deepcopy
1.488 - pure python Copy() method not copying classes (only dicts/lists/tuples)
0.325 - for item in old_list: new_list.append(item)
0.217 - [i for i in old_list] (a list comprehension)
0.186 - copy.copy(old_list)
0.075 - list(old_list)
0.053 - new_list = []; new_list.extend(old_list)
0.039 - old_list[:] (list slicing)
```

### 列表的append和extend的区别

```>>> x = [1, 2]
>>> x.append(3)
>>> x
[1, 2, 3]
>>> x.append([4,5])
>>> x
[1, 2, 3, [4, 5]]
>>>
>>> x = [1, 2, 3]
>>> x.extend([4, 5])
>>> x
[1, 2, 3, 4, 5]
```

### 如何随机地从列表中抽取变量

```foo = ['a', 'b', 'c', 'd', 'e']
from random import choice
print choice(foo)
```

### 如何利用下标从列表中删除一个元素

1.del

```In [9]: a = range(10)
In [10]: a
Out[10]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: del a[-1]
In [12]: a
Out[12]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
```

2.pop

```a = ['a', 'b', 'c', 'd']
a.pop(1)
# now a is ['a', 'c', 'd']

a = ['a', 'b', 'c', 'd']
a.pop()
# now a is ['a', 'b', 'c']
```

### 获取列表的最后一个元素

```result = l[-1]
result = l.pop()
```

### 序列的切片操作

It's pretty simple really: 很简单:

```a[start:end] # start 到 end-1
a[start:]    # start 到 末尾
a[:end]      # 0 到 end-1
a[:]         # 整个列表的拷贝
```

```a[start:end:step] # start through not past end, by step
```

```a[-1]    # 最后一个元素
a[-2:]   # 最后两个元素
a[:-2]   # 除了最后两个元素
```

Python对程序员很友好，如果序列中存在的元素数量少于你要的，例如，你请求 a[:-2] 但是a只有一个元素，你会得到一个空列表，而不是一个错误.有时候你或许希望返回的是一个错误，所以你必须知道这点

### 如何将一个列表切分成若干个长度相同的子序列

```l = range(1, 1000)
print chunks(l, 10) -> [ [ 1..10 ], [ 11..20 ], .., [ 991..999 ] ]
```

```def chunks(l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l[i:i+n]
list(chunks(range(10, 75), 10))
```

```def chunks(l, n):
return [l[i:i+n] for i in range(0, len(l), n)]
```

### 使用列表解析创建一个字典

python 2.6

```d = dict((key, value) for (key, value) in sequence)
```

python 2.7+ or 3, 使用 字典解析语法

```d = {key: value for (key, value) in sequence}
```

### 使用"in"还是"has_key()"

```d = {'a': 1, 'b': 2}
'a' in d
True
or:

d = {'a': 1, 'b': 2}
d.has_key('a')
True
```

in更pythonic, 另外 has_key()在Python3.x中已经被移除

### 字典默认值

```#获取时,如不存在，得到默认值
d.get(key, 0)
#设置时，若key不存在，设置默认值，已存在，返回已存在value
d.setdefault(key, []).append(new_element)
#初始即默认值
from collections import defaultdict
d = defaultdict(lambda: 0)
#or d = defaultdict(int)
```

### 如何给字典添加一个值

```#### Making a dictionary ####
data = {}
# OR #
data = dict()

data = {'a':1,'b':2,'c':3}
# OR #
data = dict(a=1, b=2, c=3)

#### Inserting/Updating value ####
# OR #
data.update({'a':1})
# OR #
data.update(dict(a=1))

#### Merging 2 dictionaries ####
data.update(data2)  # Where data2 is also a dict.
```

### 如何将字段转换成一个object，然后使用对象-属性的方式读取

```>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}}
```

```>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
bar
```

```>>> from collections import namedtuple
>>> MyStruct = namedtuple('MyStruct', 'a b d')
>>> s = MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s
MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s.a
1
>>> s.b
{'c': 2}
>>> s.c
>>> s.d
['hi']
```

```class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)

>>> args = {'a': 1, 'b': 2}
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s.a
1
>>> s.b
2
```

## 字符串，文件

### 字符如何转为小写

```s = "Kilometer"
print(s.lower())
```

### 如何创建不存在的目录结构

```if not os.path.exists(directory):
os.makedirs(directory)
```

### 如何拷贝一个文件

shutil模块

```copyfile(src, dst)
```

src/dst是字符串

### 字符串转为float/int

```>>> a = "545.2222"
>>> float(a)
545.2222
>>> int(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '545.2222'
>>> int(float(a))
545
>>> int('544')
544
```

```>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
```

### 如何反向输出一个字符串

```>>> 'hello world'[::-1]
'dlrow olleh'
```

### 如何随机生成大写字母和数字组成的字符串

```6U1S75
4Z4UKK
U911K4
```

```import string, random
''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(N))
```

### 逐行读文件去除换行符(perl chomp line)

```>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']
```

```#去除了空白+换行
>>> 'test string \n'.rstrip()
'test string'
#只去换行
>>> 'test string \n'.rstrip('\n')
'test string '
#更通用的做法，系统相关
>>> import os, sys
>>> sys.platform
'linux2'
>>> "foo\r\n".rstrip(os.linesep)
'foo\r'
```

### python中字符串的contains

python中字符串判断contains

```if not "blah" in somestring: continue
if "blah" not in somestring: continue
```

```s = "This be a string"
if s.find("is") == -1:
print "No 'is' here!"
else:
print "Found 'is' in the string."
```

### 如何判断一个字符串是数字

```def is_number(s):
try:
float(s)
return True
except ValueError:
return False
```

```a = "03523"
a.isdigit()
```

### 如何填充0到数字字符串中保证统一长度

```>>> n = '4'
>>> print n.zfill(3)
>>> '004'
```

```>>> n = 4
>>> print '%03d' % n
>>> 004
>>> print "{0:03d}".format(4)  # python >= 2.6
>>> 004
>>> print("{0:03d}".format(4))  # python 3
>>> 004
```

## 控制结构（条件、循环）

### 如何在循环中获取下标

```for idx, val in enumerate(ints):
print idx, val
```

### 如何判断一个变量的类型

```>>> i = 123
>>> type(i)
<type 'int'>
>>> type(i) is int
True
>>> i = 123456789L
>>> type(i)
<type 'long'>
>>> type(i) is long
True
>>> i = 123.456
>>> type(i)
<type 'float'>
>>> type(i) is float
True
```

```>>> type( [] ) == list
True
>>> type( {} ) == dict
True
>>> type( "" ) == str
True
>>> type( 0 ) == int
True

>>> class Test1 ( object ):
pass
>>> class Test2 ( Test1 ):
pass
>>> a = Test1()
>>> b = Test2()
>>> type( a ) == Test1
True
>>> type( b ) == Test2
True
>>> type( b ) == Test1
False
>>> isinstance( b, Test1 )
True
>>> isinstance( b, Test2 )
True
>>> isinstance( a, Test1 )
True
>>> isinstance( a, Test2 )
False
>>> isinstance( [], list )
True
>>> isinstance( {}, dict )
True
```

## 类

### 如何判断一个对象是否拥有某个属性

```if hasattr(a, 'property'):
a.property
```

EAFP(easier to ask for forgiveness than permission)

LBYL(look before you leap)

```try:
doStuff(a.property)
except AttributeError:
otherStuff()
or

if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
```

### Python中的类变量(环境变量)

```>>> class MyClass:
...     i = 3
...
>>> MyClass.i
3
```

i是类级别的变量，但这里要和实例级别的变量i区分开

```>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)
```

```class C:
@staticmethod
def f(arg1, arg2, ...): ...
```

### 如何定义静态方法(static method)

```class MyClass(object):
@staticmethod
def the_static_method(x):
print x
MyClass.the_static_method(2) # outputs 2
```

### @staticmethod和@classmethod的区别

staticmethod，静态方法在调用时，对类及实例一无所知

classmethod, 在调用时，将会获取到其所在的类，或者类实例，作为其第一个参数

```>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
```

### 如何获取一个实例的类名

```x.__class__.__name__
```

## 模块

### 如何列出一个目录的所有文件

1.使用os.listdir(),得到目录下的所有文件和文件夹

```#只需要文件
from os import listdir
from os.path import isfile, join
onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath,f)) ]
```

2.os.walk()

```from os import walk

f = []
for (dirpath, dirnames, filenames) in walk(mypath):
f.extend(filenames)
break
```

3.glob

```import glob
```

import os

```for dirname, dirnames, filenames in os.walk('.'):
# print path to all subdirectories first.
for subdirname in dirnames:
print os.path.join(dirname, subdirname)

# print path to all filenames.
for filename in filenames:
print os.path.join(dirname, filename)
```

### json和simplejson的区别

json就是simple，加入到标准库. json在2.6加入，simplejson在2.4+,2.6+,更有优势

```try: import simplejson as json
except ImportError: import json
```

### python中如何获取当前时间

```>>> import datetime
>>> datetime.datetime.now()
datetime(2009, 1, 6, 15, 8, 24, 78915)
```

```>>> datetime.datetime.time(datetime.datetime.now())
datetime.time(15, 8, 24, 78915))
#等价
>>> datetime.datetime.now().time()
```

```>>> from datetime import datetime
```

## 其他

### 如何从标准输入读取内容stdin

```import fileinput
for line in fileinput.input():
pass
```

### foo is None 和 foo == None的区别

```if foo is None: pass
if foo == None: pass
```

```>>> class foo(object):
def __eq__(self, other):
return True

>>> f = foo()
>>> f == None
True
>>> f is None
False

>>> list1 = [1, 2, 3]
>>> list2 = [1, 2, 3]]
>>> list1==list2
True
>>> list1 is list2
False
```

```(ob1 is ob2) 等价于 (id(ob1) == id(ob2))
```

### __init__.py是做什么用的

__init__.py让Python把目录当成包，

### 如何获取安装的python模块列表

```>>> help('modules')
```

## 环境相关

### setup.py安装后如何卸载

```python setup.py install
```

```python setup.py install --record files.txt
cat files.txt | xargs rm -rf
```

## 异常

### 如何一行内处理多个异常

```try:
# do something that may fail
except:
# do this if ANYTHING goes wrong
```

```try:
# do something that may fail
except IDontLikeYourFaceException:
# put on makeup or smile
except YouAreTooShortException:
```

```try:
# do something that may fail
except IDontLIkeYouException, YouAreBeingMeanException: #没生效
except Exception, e: #捕获了所有
```

```# as在python2.6,python2.7中仍然可以使用
except (IDontLIkeYouException, YouAreBeingMeanException) as e:
pass
```

### 如何flush Python的print输出

```import sys
sys.stdout.flush()
```

### 如何获取一个函数的函数名字符串

```my_function.__name__
>>> import time
>>> time.time.__name__
'time'
```

### 应该在学习Python3之前学习Python2，还是直接学习Python3

3要替代2不是短时间内能完成的，将会是一个很长的过程，所以学习Python2并没有什么坏处

### python中用==比较字符串，is有时候会返回错误判断

is是身份测试，==是相等测试

```>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False'
```

is 等价于 id(a) == id(b)

### 如何截取一个字符串获得子串

```>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'
```

python将这类操作称为切片，可以作用于序列类型，不仅仅是字符串

### 用函数名字符串调用一个函数

```import foo
methodToCall = getattr(foo, 'bar')
result = methodToCall()
```

```result = getattr(foo, 'bar')()
```

### 如何获取文件扩展名

```>>> import os
>>> fileName, fileExtension = os.path.splitext('/path/to/somefile.ext')
>>> fileName
'/path/to/somefile'
>>> fileExtension
'.ext'
```

### 如何获取list中包含某个元素所在的下标

```>>> ["foo","bar","baz"].index('bar')
1
```

### 如何截掉空格（包括tab)

```s = "  \t a string example\t  "
s = s.strip()
```

```s = s.rstrip()
```

```s = s.lstrip()
```

```s = s.strip(' \t\n\r')
```

### 如何将一个十六进制字符串转为整数

```>>> int("a", 16)
10
>>> int("0xa",16)
10
```

### 如何结束退出一个python脚本

```import sys
sys.exit()
```

### 如何往文件中追加文本

```with open("test.txt", "a") as myfile:
myfile.write("appended text")
```

### 如何使用不同分隔符切分字符串

```>>> re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.'])
```

```import re
DATA = "Hey, you - what are you doing here!?"
print re.findall(r"[\w']+", DATA)
# Prints ['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']
```

### 如何获取一个字符的ASCII码

```>>> ord('a')
97
>>> chr(97)
'a'
>>> chr(ord('a') + 3)
'd'
>>>
```

```>>> unichr(97)
u'a'
>>> unichr(1234)
u'\u04d2'
```

### 排序一个列表中的所有dict，根据dict内值

```[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
```

```newlist = sorted(list_to_be_sorted, key=lambda k: k['name'])
```

```from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name'))
```

### 读文件到列表中

```f = open('filename')
f.close()

with open(fname) as f:
```

### 如何用http下载一个文件

```import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
```

```import urllib2

file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()

file_size_dl = 0
block_sz = 8192
while True:
if not buffer:
break

file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status,

f.close()
```

```>>> import requests
>>>
>>> r = requests.get(url)
>>> print len(r.content)
10485760
```

### 在virtualenv中如何使用不同的python版本

```virtualenv -p /usr/bin/python2.6 <path/to/new/virtualenv/>
```

### python中如何将一行长代码切成多行

```e = 'a' + 'b' + 'c' + 'd'

e = 'a' + 'b' +
'c' + 'd'
```

```a = dostuff(blahblah1, blahblah2, blahblah3, blahblah4, blahblah5,
blahblah6, blahblah7)
```

```a = '1' + '2' + '3' + \
'4' + '5'

a = ('1' + '2' + '3' +
'4' + '5')
```

### 如何找到一个目录下所有.txt文件

```import glob
import os
os.chdir("/mydir")
for files in glob.glob("*.txt"):
print files
```

```import os
os.chdir("/mydir")
for files in os.listdir("."):
if files.endswith(".txt"):
print files
```

```import os
for r,d,f in os.walk("/mydir"):
for files in f:
if files.endswith(".txt"):
print os.path.join(r,files)
```

### 如何使用绝对路径import一个模块

```import imp

foo.MyClass()
```

### 如何在遍历一个list时删除某些玄素

```somelist = [x for x in somelist if determine(x)]
```

```#在原有对象上进行修改
somelist[:] = [x for x in somelist if determine(x)]
```

```from itertools import ifilterfalse
somelist[:] = list(ifilterfalse(determine, somelist))
```

### 如何强制使用浮点数除法

```c = a / b
```

```>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663
```

```c = a / float(b)
```

### 如何映射两个列表成为一个字典

```keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
```

```dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
```

```>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print dictionary
{'a': 1, 'b': 2, 'c': 3}
```

### 找到当前目录及文件所在目录

```import os.path
os.path.realpath(__file__)
```

### 为何1 in [1,0] == True执行结果是False

```>>> 1 in [1,0]             # This is expected
True
>>> 1 in [1,0] == True     # This is strange
False
>>> (1 in [1,0]) == True   # This is what I wanted it to be
True
>>> 1 in ([1,0] == True)   # But it's not just a precedence issue!
# It did not raise an exception on the second example.

Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
1 in ([1,0] == True)
TypeError: argument of type 'bool' is not iterable
```

```1 in [1,0] == True
```

```(1 in [1, 0]) and ([1, 0] == True)
```

```a < b < c
```

```(a < b) and (b < c) # b不会被解析两次
```

### Python中的switch替代语法

python中没有switch，有什么推荐的处理方法么

```def f(x):
return {
'a': 1,
'b': 2,
}.get(x, 9)
```

Python Cookbook中的几种方式

Readable switch construction without lambdas or dictionaries

Exception-based Switch-Case

Using a Dictionary in place of a 'switch' statement

### 如何将字符串转换为datetime

```from datetime import datetime
date_object = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
```

### 将一个字符串转为一个字典

```s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
```

```>>> import ast
>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}")
{'muffin': 'lolz', 'foo': 'kitty'}
```

```>>> help(ast.literal_eval)
Help on function literal_eval in module ast:

literal_eval(node_or_string)
Safely evaluate an expression node or a string containing a Python
expression.  The string or node provided may only consist of the following
Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
and None.
```

```>>> eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree
onerror(os.listdir, path, sys.exc_info())
File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree
names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mongo'
>>> ast.literal_eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
return _convert(node_or_string)
File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
raise ValueError('malformed string')
ValueError: malformed string
```

### Python如何检查一个对象是list或者tuple，但是不是一个字符串

```assert isinstance(lst, (list, tuple))
```

```assert not isinstance(lst, basestring)
```

### 使用 'if x is not None' 还是'if not x is None'

```Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
6 COMPARE_OP               9 (is not)
9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
6 COMPARE_OP               9 (is not)
9 RETURN_VALUE
```

```if x is not None:
```

### 如何获取一个文件的创建和修改时间

```import os.path, time
print "created: %s" % time.ctime(os.path.getctime(file))
```

```import os, time
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)
```

### 如何离开virtualenv

```me@mymachine:~\$ workon env1
(env1)me@mymachine:~\$ workon env2
(env2)me@mymachine:~\$ workon env1
(env1)me@mymachine:~\$
```

```\$ deactivate
```

### 如何认为地抛出一个异常

pythonic

```raise Exception("I know python!")
```

### 在Python中如何展示二进制字面值

```>>> 0x12AF
4783
>>> 0x100
256
```

```>>> 01267
695
>>> 0100
64
```

Python 2.5 及更早版本: 可以表示为 int('01010101111',2) 但没有字面量

Python 2.6 beta: 可以使用0b1100111 or 0B1100111 表示

Python 2.6 beta: 也可以使用 0o27 or 0O27 (第二字字符是字母 O)

Python 3.0 beta: 同2.6，但不支持027这种语法

### Python中检查类型的权威方法

```type(o) is str
```

```isinstance(o, str)
```

```issubclass(type(o), str)
type(o) in ([str] + str.__subclasses__())
```

```isinstance(o, basestring)
```

```isinstance(o, (str, unicode))
```

### 如何获取Python的site-packages目录位置

```python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
```

```from distutils.sysconfig import get_python_lib
print(get_python_lib())
```

### Python中*和的作用

args和*kwargs允许函数拥有任意数量的参数，具体可以查看 more on defining functions

*args将函数所有参数转为序列

```In [1]: def foo(*args):
...:     for a in args:
...:         print a
...:
...:

In [2]: foo(1)
1

In [4]: foo(1,2,3)
1
2
3
```

**kwargs 将函数所有关键字参数转为一个字典

```In [5]: def bar(**kwargs):
...:     for a in kwargs:
...:         print a, kwargs[a]
...:
...:

In [6]: bar(name="one", age=27)
age 27
name one
```

```def foo(kind, *args, **kwargs):
pass
```

*l的另一个用法是用于函数调用时的参数列表解包(unpack)

```In [9]: def foo(bar, lee):
...:     print bar, lee
...:
...:

In [10]: l = [1,2]

In [11]: foo(*l)
1 2
```

```first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
```

### 字符串格式化 % vs format

Python2.6中引入string.format()方法，语法和原先%操作符的字符串格式化差异较大

```#!/usr/bin/python
sub1 = "python string!"
sub2 = "an arg"

a = "i am a %s"%sub1
b = "i am a {0}".format(sub1)

c = "with %(kwarg)s!"%{'kwarg':sub2}
d = "with {kwarg}!".format(kwarg=sub2)

print a
print b
print c
print d
```

.format 看起来更加强大，可以用在很多情况.

```"hi there %s" % name
```

```"hi there %s" % (name,)   # supply the single argument as a single-item tuple
```

```你对.format知之甚少

```

### Python中什么项目结构更好

```/scripts or /bin  命令行脚本
/tests 测试
/lib C-语言包
/doc 文档
/apidoc api文档
```

```/foo
/bar
/baz
```

```Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
```

### argparse可选位置参数

dir是一个位置参数，定义如下

```parser.add_argument('dir', default=os.getcwd())
```

```parser.add_argument('dir', nargs='?', default=os.getcwd())
```

```>>> import os, argparse
>>> parser = argparse.ArgumentParser()
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
dir

optional arguments:
-h, --help  show this help message and exit
-v
```

### Python中 new 和 __init__的用法

```class A(object):
_dict = dict()

def __new__(cls):
if 'key' in A._dict:
print "EXISTS"
return A._dict['key']
else:
print "NEW"
return super(A, cls).__new__(cls)

def __init__(self):
print "INIT"
A._dict['key'] = self
print ""

a1 = A()
a2 = A()
a3 = A()
```

```NEW
INIT

EXISTS
INIT

EXISTS
INIT
```

__new__是实例创建的第一步.最先被调用，并且负责返回类的一个新实例.

### Python 'self' 解释

self关键字的作用是什么？ 我理解他用户在创建class时具体化实例，但我无法理解为何需要给每个方法加入self作为参数.

```class myClass
def myFunc(name)
@name = name
end
end
```

```class myClass:
def myFunc(self, name):
self.name = name
```

Python本来可以做一些用来区分真实的名字和属性的区别 —— 像Ruby有的特殊语法，或者像C++/Java的命令声明,或者其他可能的的语法 —— 但是Python没有这么做.Python致力于使事情变得明确简单，让事情是其本身，虽然并不是全部地方都这么做，但是实例属性石这么做的！这就是为什么给一个实例属性赋值时需要知道是给哪个实例赋值,并且，这就是为什么需要self

```class Vector(object):
def __init__(self, x, y):
self.x = x
self.y = y
def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
```

```def length_global(vector):
return math.sqrt(vector.x ** 2 + vector.y ** 2)
```

```v_instance.length()

Vector.length(v_instance)
```

### 为什么Python的'private'方法并不是真正的私有方法

Python允许我们创建'private' 函数：变量以两个下划线开头，像这样： __myPrivateMethod(). 但是，如何解释：

```>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
...
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!
```

dir(obj) 和 obj._MyClass__myPrivateMethod()

‘private'只是用作，确保子类不会意外覆写父类的私有方法和属性.不是为了保护外部意外访问而设计的！

```>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}
```

### 如何删除一个list中重复的值同时保证原有顺序

```def uniq(input):
output = []
for x in input:
if x not in output:
output.append(x)
return output
```

```def f7(seq):
seen = set()
return [ x for x in seq if x not in seen and not seen_add(x)]
```

### 有什么方法可以获取系统当前用户名么?

```>>> os.getuid()
42
'slartibartfast'
```

```>>> import getpass
>>> getpass.getuser()
'kostya'
```

### Python assert最佳实践

```assert x >= 0, 'x is less than zero'

if x < 0:
raise Exception, 'x is less than zero'

```

```原文 Also, is there any way to set a business rule like if x \< 0 raise error that is always checked without the try/except/finally so, if at anytime throughout the code x is less than 0 an error is raised, like if you set assert x < 0 at the start of a function, anywhere within the function where x becomes less then 0 an exception is raised?
```

Assert仅用在，测试那些从不发生的情况！目的是让程序尽早失败

Exception用在，那些可以明确知道会发生的错误，并且建议总是创建自己的异常类

### 在非创建全局变量的地方使用全局变量

```globvar = 0

def set_globvar_to_one():
global globvar    # Needed to modify global copy of globvar
globvar = 1

def print_globvar():
print globvar     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1
```

### 如何在单一表达式中合并两个Python字典

```>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = x.update(y)
>>> print z
None
>>> x
{'a': 1, 'b': 10, 'c': 11}
```

```z = dict(x.items() + y.items())
```

```>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}
```

```>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
```

### 如何使用 pip 更新所有包

```pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs pip install -U
```

### Python中声明exception的方法

```>>> class MyError(Exception):
...     def __init__(self, message):
...         self.message = message
...
>>> MyError("foo")
_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
```

```class MyException(Exception):
pass
```

```class ValidationError(Exception):
def __init__(self, message, Errors):

# Call the base class constructor with the parameters it needs
Exception.__init__(self, message)

# Now for your custom code...
self.Errors = Errors
```

### 在Python中使用Counter错误

```AttributeError: 'module' object has no attribute 'Counter'

from collections import Counter
ImportError: cannot import name Counter
```

### 如何删除Python easy_install安装的包

pip, setuptools/easy_install的另一种选择，提供uninstall命令

```\$ easy_install -m [PACKAGE]
```

```\$ rm -rf .../python2.X/site-packages/[PACKAGE].egg
```

### 在Python中如何解析xml

```<foo>
<bar>
<type foobar="1"/>
<type foobar="2"/>
</bar>
</foo>
```

```for atype in e.findall('type')
print(atype.get('foobar'))
```

### 如何将一个Python time.struct_time对象转换为一个datetime对象

```from time import mktime
from datetime import datetime

dt = datetime.fromtimestamp(mktime(struct))
```
::...