Python基础语法

最近在学Python,主要代码整理自廖雪峰博客:

Python教程 - 廖雪峰的官方网站

基础

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

print 'I\'m \"OK\"!'

a = 123  # a是整数

print a

a = 'ABC'  # a变为字符串

print a

a = 100

if a >= 0:  # 注意冒号

    print a

else:

    print -a

# int转成string,函数int(string)

# string转成int,函数str(number)

print len(u'ABC')

print 'Hi, %s, you have $%d.' % ('Michael', 1000000)

print 'Age: %s. Gender: %s' % (25, True)

classmates = ['Michael''Bob''Tracy']

classmates.append('Adam')

classmates.insert(1, 'Jack')

classmates.pop()

classmates.pop(1)

classmates[1] = 123  # 类型可以不同

# 相等的

print classmates

print classmates[len(classmates) - 1] == classmates[-1]

print classmates[len(classmates) - 2] == classmates[-2]

# tuple和list非常类似,但是tuple一旦初始化就不能修改,没有append(),insert()这样的方法

# 可以正常地使用classmates[-1],但不能赋值成另外的元素

t = ('Michael''Bob''Tracy')

t = (1,);  # 只有1个元素的tuple定义时必须加一个逗号,,来消除歧义

t = (1, 2)

print t

# 如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else

# 下面打印  teenager

age = 20

if age >= 6:

    print 'teenager'

elif age >= 18:

    print 'adult'

else:

    print 'kid'

sum = 0

for in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:

    sum = sum + x

print sum

sum = 0

for in range(101):

    sum = sum + x

print sum

sum = 0

n = 99

while n > 0:

    sum = sum + n

    n = n - 2

print sum

# 打印

# name = raw_input('please enter your name: ')

# print 'hello,', name

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}

print d['Michael']

d['Adam'] = 67

print d['Adam']

# 要避免key不存在的错误

print 'Thomas' in d

print d.get('Thomas')

print d.get('Thomas', -1)

d.pop('Bob')

key = [1, 2, 3]

# key的对象就不能变,而list是可变的,就不能作为key

# d[key] = 'a list'

print d

# 要创建一个set,需要提供一个list作为输入集合

s1 = set([1, 2, 3])

# 重复元素在set中自动被过滤

s1 = set([1, 1, 2, 2, 3, 3])

s1.add(4)

s1.remove(4)

s2 = set([2, 3, 4])

# 交集、并集

print s1 & s2, s1 | s2

# 对于可变对象,比如list,对list进行操作,list内部的内容是会变化的

a = ['c''b''a']

a.sort()

print a

# 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。

# 相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

a = 'abc'

b = a.replace('a''A')

print a, b

  

函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

# 函数

# 比较函数

print cmp(1, 2)

# 数据类型转换

print int('123')

print int(12.34)

str(1.23)

unicode(100)

bool(1)

bool('')

# 定义函数,如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。

# return None可以简写为return,函数执行完毕没有return语句时,自动return None。

# 只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance实现

def my_abs(x):

    if not isinstance(x, (intfloat)):

        raise TypeError('bad operand type')

    if x >= 0:

        return x

    else:

        return -x

a = my_abs  # 变量a指向abs函数

print a(-1)  # 所以也可以通过a调用abs函数

# 空函数

# 如果想定义一个什么事也不做的空函数,可以用pass语句

# pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来

# 缺少了pass,代码运行就会有语法错误。

def nop():

    pass

# 可以返回多个值,实际是返回tuple,这样写起来方便

def move(x, y, step, angle=0):

    nx = x + step * math.cos(angle)

    ny = y - step * math.sin(angle)

    return nx, ny

x, y = move(100, 100, 60, math.pi / 6)

print x, y

r = move(100, 100, 60, math.pi / 6)

print r

# 默认参数,必选参数在前,默认参数在后

# 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。

def power(x, n=2):

    s = 1

    while n > 0:

        n = n - 1

        s = s * x

    return s

print power(5), power(5, 3)

def enroll(name, gender, age=6, city='Beijing'):

    print 'name:', name

    print 'gender:', gender

    print 'age:', age

    print 'city:', city

print  enroll('Sarah''F')

print enroll('Bob''M', 7)

# 当不按顺序提供部分默认参数时,需要把参数名写上

print enroll('Adam''M', city='Tianjin')

def add_end(L=[]):

    L.append('END')

    return L

print add_end()

print add_end()  # ['END''END'],不对

# 默认参数必须指向不变对象!,修改上面的例子,否则运行会有逻辑错误!

def add_end(L=None):

    if is None:

        L = []

    L.append('END')

    return L

# 可变参数,在参数前面加了一个*号

def calc(*numbers):

    sum = 0

    for in numbers:

        sum = sum + n * n

    return sum

print calc(1, 2)

print calc()

# 如果已经有一个list或者tuple,要调用一个可变参数怎么办?

nums = [1, 2, 3]

print calc(nums[0], nums[1], nums[2])

print calc(*nums)

# 关键字参数,可以扩展函数的功能

# 比如,在person函数里,我们保证能接收到name和age这两个参数,

# 但是,如果调用者愿意提供更多的参数,我们也能收到

def person(name, age, **kw):

    print 'name:', name, 'age:', age, 'other:', kw

person('Michael', 30)

# name: Michael age: 30 other: {}

person('Bob', 35, city='Beijing')

# name: Bob age: 35 other: {'city': 'Beijing'}

person('Adam', 45, gender='M', job='Engineer')

# name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

kw = {'city''Beijing''job''Engineer'}

person('Jack', 24, city=kw['city'], job=kw['job'])

person('Jack', 24, **kw)

# 参数组合

# 在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用

# 注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。

def func(a, b, c=0, *args, **kw):

    print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw

print func(1, 2)

# a = 1 b = 2 c = 0 args = () kw = {}

print func(1, 2, c=3)

# a = 1 b = 2 c = 3 args = () kw = {}

print func(1, 2, 3, 'a''b')

# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}

print func(1, 2, 3, 'a''b', x=99)

# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}

# 要注意定义可变参数和关键字参数的语法:

# *args是可变参数,args接收的是一个tuple;

# **kw是关键字参数,kw接收的是一个dict。

args = (1, 2, 3, 4)  # tuple

kw = {'x': 99}  # dict

print func(*args, **kw)

# a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}

# 递归

def fact(n):

    if n == 1:

        return 1

    return n * fact(n - 1)

# 尾递归

def fact(n):

    return fact_iter(n, 1)

# 切片

def fact_iter(num, product):

    if num == 1:

        return product

    return fact_iter(num - 1, num * product)

L = ['Michael''Sarah''Tracy''Bob''Jack']

r = []

n = 3

for in range(n):

    r.append(L[i])

# 迭代

print r

# 切片(Slice)操作符,取前3个元素,用一行代码就可以完成

print L[0:3]

# 如果第一个索引是0,还可以省略

print L[:3]

# 取倒数第一个元素

print L[-2:-1]

# 取后俩个元素

print L[-2:]

# 原样复制一个list:

print L[:]

# tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:

print (0, 1, 2, 3, 4, 5)[:3]

print 'ABCDEFG'[:3]

# 只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代

# 遍历key

d = {'a': 1, 'b': 2, 'c': 3}

for key in d:

    print key

# 遍历value

for value in d.itervalues():

    print value

# 遍历key,value

for k, v in d.iteritems():

    print k, '=', v

for ch in 'ABC':

    print ch

from collections import Iterable

print isinstance([1, 2, 3], Iterable)  # list是否可迭代

print isinstance('abc', Iterable)  # str是否可迭代

print isinstance(123, Iterable)  # 整数是否可迭代,false

print isinstance(x, str)  # 判断一个变量是不是字符串

# 这样就可以在for循环中同时迭代索引和元素本身

for i, value in enumerate(['A''B''C']):

    print i, value

for x, y in [(1, 1), (2, 4), (3, 9)]:

    print x, y

# 列表生成式

print range(1, 11)

L = []

# [1x1, 2x2, 3x3, ..., 10x10]

for in range(1, 11):

    L.append(x * x)

print [x * x for in range(1, 11)]

# 筛选出仅偶数的平方

print [x * x for in range(1, 11) if x % 2 == 0]

# 两层循环,可以生成全排列

print [m + n for in 'ABC' for in 'XYZ']

# 列出当前目录下的所有文件和目录名

print [d for in os.listdir('.')]  # os.listdir可以列出文件和目录

L = ['Hello''World''IBM''Apple']

# 一个list中所有的字符串变成小写

print [s.lower() for in L]

# 生成器:如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的空间

# 和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator

L = [x * x for in range(10)]

g = (x * x for in range(10))

print g.next()

for in g:

    print n

# 如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

def odd():

    print 'step 1'

    yield 1

    print 'step 2'

    yield 3

    print 'step 3'

    yield 5

# 在执行过程中,遇到yield就中断,下次又继续执行

# 基本上从来不会用next()来调用它,而是直接使用for循环来迭代

o = odd()

print o.next()

print o.next()

print o.next()

# 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

# 函数的名字也是变量

def add(x, y, f):

    return f(x) + f(y)

print(add(-5, 6, abs))

def f(x):

    return x * x

# map()函数接收两个参数,一个是函数,一个是Iterable,

# map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回

r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

print list(r)

# for也能实现,太麻烦

L = []

for in [1, 2, 3, 4, 5, 6, 7, 8, 9]:

    L.append(f(n))

print(L)

print list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

# reduce把结果继续和序列的下一个元素做累积计算

# reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

def add(x, y):

    return x + y

print reduce(add, [1, 3, 5, 7, 9]) \

    # 求和运算可以直接用Python内建函数sum(),没必要动用reduce。

# print sum([1, 3, 5, 7, 9])

def fn(x, y):

    return x * 10 + y

print reduce(fn, [1, 3, 5, 7, 9])

def char2num(s):

    digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

    return digits[s]

print reduce(fn, map(char2num, '13579'))

# 简化

DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def str2int(s):

    def fn(x, y):

        return x * 10 + y

    def char2num(s):

        return DIGITS[s]

    return reduce(fn, map(char2num, s))

# 用lambda函数进一步简化

def char2num(s):

    return DIGITS[s]

def str2int(s):

    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

print str2int('13579')

# filter()函数用于过滤序列

# 根据返回值是True还是False决定保留还是丢弃该元素

def is_odd(n):

    return n % 2 == 1

print list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))

def not_empty(s):

    return s and s.strip()

print list(filter(not_empty, ['A''''B', None, 'C''  ']))

print sorted([36, 5, -12, 9, -21])

print sorted([36, 5, -12, 9, -21], key=abs)

print sorted(['bob''about''Zoo''Credit'])

# 排序应该忽略大小写,按照字母序排序

print sorted(['bob''about''Zoo''Credit'], key=str.lower)

print sorted(['bob''about''Zoo''Credit'], key=str.lower, reverse=True)

def lazy_sum(*args):

    def sum():

        ax = 0

        for in args:

            ax = ax + n

        return ax

    return sum

# 闭包,函数作为返回值

# 返回的函数并没有立刻执行,而是直到调用了f()才执行。

f1 = lazy_sum(1, 3, 5, 7, 9)

f2 = lazy_sum(1, 3, 5, 7, 9)

print f1() == f2()  # true,比较的值

print f1 == f2  # false,引用不同,所以f1()和f2()的调用结果互不影响。

def count():

    fs = []

    for in range(1, 4):

        def f():

            return i * i

        fs.append(f)

    return fs

# 全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。

# 等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9

# 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

f1, f2, f3 = count()

def count():

    def f(j):

        def g():

            return j * j

        return g

    fs = []

    for in range(1, 4):

        fs.append(f(i))  # f(i)立刻被执行,因此i的当前值被传入f()

    return fs

f1, f2, f3 = count()  # 1,4,9

# 匿名函数

# 冒号前面的x表示函数参数

print list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

# 匿名函数lambda x: x * x,实际上就是

def f(x):

    return x * x

# 可以把匿名函数赋值给一个变量,再利用变量来调用该函数

# 也可以把匿名函数作为返回值返回

f = lambda x: x * x

print f(4)

# 假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,

# 这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

def log(func):

    def wrapper(*args, **kw):

        print('call %s():' % func.__name__)

        return func(*args, **kw)

    return wrapper

@log

def now():

    print('2015-3-25')

print now()

# 偏函数:当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,

# 这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

int2 = functools.partial(intbase=2)

# 不需要我们自己定义

def int3(x, base=2):

    return int(x, base)

print int2('1000000')

print int3('1000000')

# 作者

__author__ = 'Michael Liao'

def _private_1(name):

    return 'Hello, %s' % name

def _private_2(name):

    return 'Hi, %s' % name

# 类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用

# 公开greeting()函数,而把内部逻辑用private函数隐藏起来

def greeting(name):

    if len(name) > 3:

        return _private_1(name)

    else:

        return _private_2(name)

  

面向对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

# 面向过程

import logging

import types

std1 = {'name''Michael''score': 98}

std2 = {'name''Bob''score': 81}

def print_score(std):

    print('%s: %s' % (std['name'], std['score']))

# 面向对象

class Student(object):

    def __init__(self, name, score):

        self.__name = name

        self.score = score

    # self指向创建的实例本身,可以不传

    # 实现数据的封装

    def print_score(self):

        print('%s: %s' % (self.__name, self.score))

    def get_name(self):

        return self.__name

    def set_name(self, name):

        self.__name = name

bart = Student('Bart Simpson', 59)

lisa = Student('Lisa Simpson', 87)

bart.print_score()

lisa.print_score()

print lisa.get_name(), lisa.score

class Animal(object):

    def run(self):

        print 'Animal is running...'

class Dog(Animal):

    def run(self):

        print 'Dog is running...'

class Cat(Animal):

    def run(self):

        print 'Cat is running...'

# 多态

def run_twice(animal):

    if (isinstance(animal, Animal)):

        animal.run()

    else:

        print "类型错误"

print run_twice(Cat())

print run_twice(Student('Bart Simpson', 59));

# 对于class的继承关系来说,使用type()就很不方便。

# 我们要判断class的类型,可以使用isinstance()函数。

print type('abc') == types.StringType

print type(u'abc') == types.UnicodeType

print type([]) == types.ListType

print type(str) == types.TypeType

print  dir('ABC')

class Student(object):

    pass

s = Student()

s.name = 'Michael'  # 动态给实例绑定一个属性

print s.name

def set_age(self, age):  # 定义一个函数作为实例方法

    self.age = age

from types import MethodType

s.set_age = MethodType(set_age, s, Student)  # 给实例绑定一个方法

s.set_age(25)  # 调用实例方法

print s.age  # 测试结果

s2 = Student()  # 创建新的实例

# print s2.set_age(25)  # 尝试调用方法,不能

def set_score(self, score):

    self.score = score

# 为了给所有实例都绑定方法,可以给class绑定方法

Student.set_score = MethodType(set_score, None, Student)

# 定义一个特殊的__slots__变量,来限制该class能添加的属性,但对子类不起作用

class Student(object):

    __slots__ = ('name''age')  # 用tuple定义允许绑定的属性名称

s = Student()  # 创建新的实例

s.name = 'Michael'  # 绑定属性'name'

s.age = 25  # 绑定属性'age'

# s.score = 99  # 不能绑定属性'score'

# 该属性不是直接暴露的,而是通过getter和setter方法来实现

class Student(object):

    @property

    def score(self):

        return self._score

    @score.setter

    def score(self, value):

        if not isinstance(value, int):

            raise ValueError('score must be an integer!')

        if value < 0 or value > 100:

            raise ValueError('score must between 0 ~ 100!')

        self._score = value

s = Student()

s.score = 60  # OK,实际转化为s.set_score(60)

s.score  # OK,实际转化为s.get_score()

# s.score = 9999

print s.score  # 实际转化为s.get_score()

# 还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

class Student(object):

    @property

    def birth(self):

        return self._birth

    @birth.setter

    def birth(self, value):

        self._birth = value

    @property

    def age(self):

        return 2014 - self._birth

# 可以多继承

# class Dog(Mammal, RunnableMixin, CarnivorousMixin):

#     pass

# 定制类

# __str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串

class Student(object):

    def __init__(self, name):

        self.name = name

    def __str__(self):

        return 'Student object (name=%s)' % self.name

    __repr__ = __str__

s = Student('Michael')

print s

print Student('Michael')

# 要表现得像list那样按照下标取出元素,需要实现__getitem__()方法

class Fib(object):

    def __getitem__(self, n):

        a, b = 1, 1

        for in range(n):

            a, b = b, a + b

        return a

f = Fib()

# print f(0), f(100)

# 只有在没有找到属性的情况下,才调用__getattr__,已有的属性,不会在__getattr__中查找。

class Student(object):

    def __getattr__(self, attr):

        if attr == 'age':

            # return 25

            return lambda: 25  # 可以retrun函数,调用方式不一样了

        raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

s = Student()

print s.age()

class Chain(object):

    def __init__(self, path=''):

        self._path = path

    def __getattr__(self, path):

        return Chain('%s/%s' % (self._path, path))

    def __str__(self):

        return self._path

print Chain().status.user.timeline.list

# 任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用(像方法一样)

class Student(object):

    def __init__(self, name):

        self.name = name

    def __call__(self):

        print('My name is %s.' % self.name)

s = Student('Michael')

print s()

# 怎么判断一个变量是对象还是函数呢?

# print callable(Student())

# print callable([1, 2, 3])

def foo(s):

    return 10 / int(s)

def bar(s):

    return foo(s) * 2

# logging模块可以非常容易地记录错误信息

def main():

    try:

        bar('0')

    except StandardError, e:

        logging.exception(e)

        print 'Error!'

    finally:

        print 'finally...'

# 只要main()捕获到了,就可以处理

print main()

# assert的意思是,表达式n != 0应该是True,否则,后面的代码就会出错。

# 如果断言失败,assert语句本身就会抛出AssertionError:

def foo(s):

    n = int(s)

    assert n != 0, 'n is zero!'

    return 10 / n

def main():

    foo('0')

# 和assert比,logging不会抛出错误,而且可以输出到文件

logging.basicConfig(level=logging.INFO)

s = '0'

n = int(s)

logging.info('n = %d' % n)

print 10 / n

  

线程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

# 新线程执行的代码:

# 主线程实例的名字叫MainThread,子线程的名字在创建时指定,我们用LoopThread命名子线程

import threading

import time

def loop():

    print 'thread %s is running...' % threading.current_thread().name

    n = 0

    while n < 5:

        n = n + 1

        print 'thread %s >>> %s' % (threading.current_thread().name, n)

        time.sleep(1)

    print 'thread %s ended.' % threading.current_thread().name

print 'thread %s is running...' % threading.current_thread().name

t = threading.Thread(target=loop, name='LoopThread')

t.start()

t.join()

print 'thread %s ended.' % threading.current_thread().name

# 线程间通讯问题(生产者消费者)

# 假定这是你的银行存款:

balance = 0

def change_it(n):

    # 先存后取,结果应该为0:

    global balance

    balance = balance + n

    balance = balance - n

# def run_thread(n):

#     for i in range(100000):

#         change_it(n)

# 需要上锁

lock = threading.Lock()

def run_thread(n):

    for in range(100000):

        # 先要获取锁:

        lock.acquire()

        try:

            # 放心地改吧:

            change_it(n)

        finally:

            # 改完了一定要释放锁:

            lock.release()

t1 = threading.Thread(target=run_thread, args=(5,))

t2 = threading.Thread(target=run_thread, args=(8,))

t1.start()

t2.start()

t1.join()

t2.join()

print balance

# 创建全局ThreadLocal对象

# 每个Thread对它都可以读写student属性,但互不影响。也不用加锁

# ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,

# 这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

local_school = threading.local()

def process_student():

    print 'Hello, %s (in %s)' % (local_school.student, threading.current_thread().name)

def process_thread(name):

    # 绑定ThreadLocal的student:

    local_school.student = name

    process_student()

t1 = threading.Thread(target=process_thread, args=('Alice',), name='Thread-A')

t2 = threading.Thread(target=process_thread, args=('Bob',), name='Thread-B')

t1.start()

t2.start()

t1.join()

t2.join()

# 协程

# consumer函数是一个generator(生成器),把一个consumer传入produce后:

# 首先调用c.next()启动生成器;

# 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

# consumer通过yield拿到消息,处理,又通过yield把结果传回;

# produce拿到consumer处理的结果,继续生产下一条消息;

# produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

# 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

def consumer():

    r = ''

    while True:

        n = yield r

        if not n:

            return

        print('[CONSUMER] Consuming %s...' % n)

        time.sleep(1)

        r = '200 OK'

def produce(c):

    c.next()

    n = 0

    while n < 5:

        n = n + 1

        print('[PRODUCER] Producing %s...' % n)

        r = c.send(n)

        print('[PRODUCER] Consumer return: %s' % r)

    c.close()

if __name__ == '__main__':

    c = consumer()

    produce(c)

  

IO操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

# os模块封装了操作系统的目录和文件操作,要注意这些函数有的在os模块中,有的在os.path模块中

# 要读取二进制文件,比如图片、视频等等,用'rb'模式打开文件

import codecs

import json

import os

import random

import threading

import time

try:

    f = open('D:\heihei.txt''r')

    print f.read()

    # 如果文件很小,read()一次性读取最方便;

    # 如果不能确定文件大小,反复调用read(size)比较保险;

    # 如果是配置文件,调用readlines()最方便

    for line in f.readlines():

        print(line.strip())  # 把末尾的'\n'删掉

finally:

    if f:

        f.close()

# 上面太繁琐引入了with语句来自动帮我们调用close()方法

with open('D:\heihei.txt''r'as f:

    print f.read()

# 判断文件是否存在

if os.path.isdir(f):

    pass

else:

    os.makedirs(f)

# 直接读出unicode

# with codecs.open('D:/gbk.txt', 'r', 'gbk') as f:

#     f.read() # u'\u6d4b\u8bd5'

print os.name  # 操作系统名字

print os.environ

print os.getenv('PATH')

# 查看当前目录的绝对路径:

print os.path.abspath('.')

# # 在某个目录下创建一个新目录,

# # 首先把新目录的完整路径表示出来:

# os.path.join(os.path.abspath('.'), 'testdir')

# # 然后创建一个目录:

# os.mkdir(os.path.abspath('.') + '/testdir')

# # 删掉一个目录:

# os.rmdir(os.path.abspath('.') + '/testdir')

# 分离路径和名字

print os.path.split('/Users/michael/testdir/file.txt')

# 可以轻松拿到扩展名

print os.path.splitext('/path/to/file.txt')

# 对文件重命名(需要有这个文件)

# os.rename('test.txt', 'test.py')

# 删除文件

# os.remove('test.py')

# 列出当前目录下的所有目录

print [x for in os.listdir('.'if os.path.isdir(x)]

# 列出所有的.py文件

print [x for in os.listdir('.'if os.path.isfile(x) and os.path.splitext(x)[1] == '.py']

try:

    import cPickle as pickle

except ImportError:

    import pickle

# 序列化

d = dict(name='Bob', age=20, score=88)

# 方法1:pickle.dumps()方法把任意对象序列化成一个str,然后,就可以把这个str写入文件

s = pickle.dumps(d)

# 反序列化

d = pickle.loads(s)

print d

# 方法2:pickle.dump()直接把对象序列化后写入一个file-like Object:

f = open('dump.txt''wb')

pickle.dump(d, f)

f.close()

# 反序列化

f = open('dump.txt''rb')

d = pickle.load(f)

f.close()

print d

# 字典转化成json,也有俩种方法

d = dict(name='Bob', age=20, score=88)

s = json.dumps(d)

print json.loads(s)

# 对象序列号

class Student(object):

    def __init__(self, name, age, score):

        self.name = name

        self.age = age

        self.score = score

s = Student('Bob', 20, 88)

def student2dict(std):

    return {

        'name': std.name,

        'age': std.age,

        'score': std.score

    }

# Student实例首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON

print(json.dumps(s, default=student2dict))

# 把任意class的实例变为dict

s = json.dumps(s, default=lambda obj: obj.__dict__)

print(s)

# 反序列化

def dict2student(d):

    return Student(d['name'], d['age'], d['score'])

print(json.loads(s, object_hook=dict2student))

# 进程和线程

# mac里这样创建

# print 'Process (%s) start...' % os.getpid()

# pid = os.fork()  # 创建一个进程

# if pid == 0:

#     print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())

# else:

#     print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)

from multiprocessing import Process, Pool, Queue

# windows下,子进程要执行的代码

def run_proc(name):

    print 'Run child process %s (%s)...' % (name, os.getpid())

# 如果要启动大量的子进程,可以用进程池的方式批量创建子进程

if __name__ == '__main__':

    print 'Parent process %s.' % os.getpid()

    p = Process(target=run_proc, args=('test',))

    print 'Process will start.'

    p.start()

    p.join()

    print 'Process end.'

def long_time_task(name):

    print 'Run task %s (%s)...' % (name, os.getpid())

    start = time.time()

    time.sleep(random.random() * 3)

    end = time.time()

    print 'Task %s runs %0.2f seconds.' % (name, (end - start))

if __name__ == '__main__':

    print 'Parent process %s.' % os.getpid()

    p = Pool()

    for in range(5):

        p.apply_async(long_time_task, args=(i,))

    print 'Waiting for all subprocesses done...'

    p.close()

    p.join()

    print 'All subprocesses done.'

# 进程间通信

# 写数据进程执行的代码:

def write(q):

    for value in ['A''B''C']:

        print 'Put %s to queue...' % value

        q.put(value)

        time.sleep(random.random())

# 读数据进程执行的代码:

def read(q):

    while True:

        value = q.get(True)

        print 'Get %s from queue.' % value

if __name__ == '__main__':

    # 父进程创建Queue,并传给各个子进程:

    q = Queue()

    pw = Process(target=write, args=(q,))

    pr = Process(target=read, args=(q,))

    # 启动子进程pw,写入:

    pw.start()

    # 启动子进程pr,读取:

    pr.start()

    # 等待pw结束:

    pw.join()

    # pr进程里是死循环,无法等待其结束,只能强行终止:

    pr.terminate()

  

网络编程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

# 客户端

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立连接:

s.connect(('192.168.202.2', 9999))

# 接收欢迎消息:

print s.recv(1024)

for data in ['Michael''Tracy''Sarah']:

    # 发送数据:

    s.send(data)

    print s.recv(1024)

s.send('exit')

s.close()

# tcp

# 服务器要能够区分一个Socket连接是和哪个客户端绑定的。

# 一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来唯一确定一个Socket。

# 创建一个socket:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立连接:

s.connect(('www.sina.com.cn', 80))

# 发送数据:

s.send('GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')

# 接收数据:

buffer = []

while True:

    # 每次最多接收1k字节:

    d = s.recv(1024)

    if d:

        buffer.append(d)

    else:

        break

data = ''.join(buffer)

# 关闭连接:

s.close()

header, html = data.split('\r\n\r\n', 1)

print header

# 把接收的数据写入文件:

with open('sina.html''wb'as f:

    f.write(html)

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# 服务端

def tcplink(sock, addr):

    print 'Accept new connection from %s:%s...' % addr

    sock.send('Welcome!')

    while True:

        data = sock.recv(1024)

        time.sleep(1)

        if data == 'exit' or not data:

            break

        sock.send('Hello, %s!' % data)

    sock.close()

    print 'Connection from %s:%s closed.' % addr

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 监听端口:

s.bind(('192.168.202.2', 9999))

s.listen(5)

print 'Waiting for connection...'

while True:

    # 接受一个新连接:

    sock, addr = s.accept()

    # 创建新线程来处理TCP连接:

    t = threading.Thread(target=tcplink, args=(sock, addr))

    t.start()

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值