python与设计模式_论 Python 与设计模式 by 赖勇浩

第1页

+

论 Python 与设计模式 

赖勇浩(http://laiyonghao.com)

2013-­‐12-­‐8

珠海

第2页

+

设  计模式? 

第3页

+

自  我介绍 

n

赖勇浩

n

从业 8 年多,主要编程语言是 

Python

n

game

-­‐>

webgame

-­‐>

web

n

常在珠三角技术沙龙出没

n

http://laiyonghao.com

3

第4页

+

P  yCon

的老朋友 

4

第5页

+

好,正式开始吧! 

5

第6页

+

先  热热场子…… 

n

写 Python

代码赚钱的,有没有?

6

第7页

+

先  热热场子…… 

n

写 Python

代码赚钱的,有没有?

n

写 Python 超过 1 年的,有没有?

7

第8页

+

再  热热场子…… 

n

读过《设计模式——可复用面向对 象软件的基础》这本书的有没有?

8

第9页

+

再  热热场子…… 

n

读过《设计模式——可复用面向对 象软件的基础》这本书的有没有?

n

读过《Head

First 设计模式》 的有没有?

9

第10页

10

一个观点 

第11页

+

我也希望是这样…… 

但事实是…… 

11

第12页

+

先  看事实:工厂函数(方法) 

int(…)

float(…)

type(name,

bases,

dict)

>>>

class

X(object):

...

a

=

1

...

>>>

X

=

type('X',

(object,),

dict(a=1))

collections.namedtuple() 

datatime.fromtimestamp(…)

Decimal.from_float(…)

Fraction.from_float(…)

Fraction.from_decimal(…) 

第13页

+

先  看事实:享元(FlyWeight) 

>>>

i

=

10

>>>

j

=

5

+

5

>>>

id(i)

140479275503872

>>>

id(j)

140479275503872

>>>

a

=

'ab'

>>>

b

=

'a'

+

'b'

>>>

id(a)

==

id(b)

True

13

第14页

+

先  看事实:享元(FlyWeight) 

14

>>>

i

=

10

>>>

j

=

5

+

5

>>>

id(i)

140479275503872

>>>

id(j)

140479275503872

>>>

a

=

'ab'

>>>

b

=

'a'

+

'b'

>>>

id(a)

==

id(b)

True

>>>

a

=

a

*

10

>>>

intern(a)

'abababababababababab'

>>>

b

=

'abababababababababab’

>>>

c

=

'abababababababababa'

+

'b’

>>>

d

=

'ab'

*

10

>>>

id(a)

==

id(b)

==

id(c)

==

id(d)

True

第15页

+

先  看事实:适配器 

15

import

SocketServer

class

ThreadedTCPServer(SocketServer.ThreadingMixIn,

SocketServer.TCPServer):

pass

第16页

+

先  看事实:代理模式 

16

>>>

import

weakref

>>>

class

A(object):pass

...

>>>

a

=

A()

>>>

a.attr

=

1

>>>

a.attr

1

>>>

a1

=

weakref.proxy(a)

>>>

a1.attr

1

>>>

a1

at

0x10dc375d0

to

A

at

0x10dc3a410>

第17页

+

先  看事实:模板方法 

17

import

SocketServer

class

MyTCPHandler(SocketServer.BaseRequestHandler):

def

handle(self):

self.data

=

self.request.recv(1024).strip()

print

"{}

wrote:".format(self.client_address[0])

print

self.data

self.request.sendall(self.data.upper())

第18页

+

先  看事实:模板方法 

From

abc

import

ABCMeta

class

C:

__metaclass__

=

ABCMeta

@abstractmethod

def

my_abstract_method(self,

...):

... 

18

第19页

+

所  以,真相是…… 

n

标准库都在用……

n

标准库都推荐用……

n

怎么可以说不需要?!

19

第20页

20

+

以我们不是不需要模式…… 

而是要 Pythonic 的模式实现…… 

第21页

+

不   Pythonic 的设计模式:单例 

21

class

Singleton(object):

def

__new__(cls,

*args,

**kw):

if

not

hasattr(cls,

'_instance'):

orig

=

super(Singleton,

cls)

cls._instance

=

orig.__new__(cls,

*args,

**kw)

return

cls._instance

第22页

+

单  例的三个需求: 

n

只能有一个实例;

n

它必须自行创建这个实例;

n

它必须自行向整个系统提供这个

实例。

22

第23页

+

单  例遇上并行 

class

Singleton(object):

objs

=

{}

objs_locker

=

threading.Lock()

def

__new__(cls,

*args,

**kv):

if

cls

in

cls.objs:

return

cls.objs[cls]

23

第24页

+

单  例遇上并行 

cls.objs_locker.acquire()

try:

if

cls

in

cls.objs:

return

cls.objs[cls]

cls.objs[cls]

=

object.__new__(cls)

finally:

cls.objs_locker.release() 

24

第25页

+

P  ythonic

的设计模式:单例 

25

n

重新审视 Python 的语法元素,尽量利用已有基础设施。

n

模块

n

所有的变量都会绑定到模块;  n

模块只初始化一次;

n

import

机制是线程安全的(保证了在并发状态下模块也只有一个实

例); 

n

惯用法:

n

文件名首字母大写,如 Moon.py

n

__all__ 

第26页

+

不   Pythonic 的设计模式:装饰器 

26

第27页

+

代  码大概是这样的 

class

darkroast(Beverage):

def

cost(self):return

0.99

class

Whip(Beverage):

def

__init__(self,

beverage):

self._beverage

=

beverage

def

cost(self):

return

self._beverage.cost()

+

0.1

print

Whip(Mocha(darkroast())).cost()

27

第28页

+

P  ythonic 的设计模式:装饰器 

def

beverage(cost):

def

_(orig

=

0.0):

return

orig

+

cost

return

_

darkroast

=

beverage(0.99)

whip

=

beverage(0.1)

mocha

=

beverage(0.2)

print

whip(mocha(darkroast()))

28

第29页

+

其  它设计模式:Borg(MonoState) 

29

n

保持对象的唯一性并不重要,只 要共享状态就行

n

Alex

Martelli

n

http:// code.activestate.com/ recipes/66531/

第30页

+

其  它设计模式:Borg(MonoState) 

30

class

Borg(object):

_state

=

{}

def

__new__(cls,

*args,

**kw):

ob

=

super(Borg,

cls).__new__(cls,

*args,

**kw)

ob.__dict__

=

cls._state

return

ob

第31页

+

动  态语言特有的设计模式:mixin 

31

n

动态地改变实例的类型的基类,在不修改生成实例过程的情况下, 给实例增加(改变)功能。可用以实现插件框架。

class

Bird(object):pass

bird

=

Bird()

class

FlyMixin:

def

fly(self):print

'I

can

fly.'

bird.__class__.__bases__

+=

(FlyMixin,

)

bird.fly()

第32页

+

动  态语言特有的模式:duck

typing  32

n

一个对象有效的语义,不是由继承自特定的类或实现特定的接口, 而是由当前方法和属性的集合决定。

n

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子, 那么这只鸟就可以被称为鸭子。(James

Whitcomb

Riley)

n

干掉模板方法?

n

不,模板方法是想要保证子类实现接口 

第33页

+

利  用设计模式提供更好的接口 

33

n

getopt

n

optparse

n

argparse

n

docopt 

n

Command-­‐line

interface

description

language

n

define

interface

for

your

command-­‐line

app,

and

n

automatically

generate

parser

for

it.

n

解释器模式 

第34页

+

d  ocopt 

34

第35页

+

解  释器模式的应用 

n

GM 指令

player

0

money

10000

player

0

attack

10000

monster

0

die

scene

monsters

die

n

过场剧情脚本

monster

0

spawn

0,0

monster

0

moveto

0,-­‐10

monster

0

attack

monster

0

moveto

0,0 

35

第36页

+

Q&A 

mail@laiyonghao.com

36

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值