Skip to content

Commit 8063ddc

Browse files
committed
add python OOP
1 parent 283ace9 commit 8063ddc

File tree

3 files changed

+84
-8
lines changed

3 files changed

+84
-8
lines changed

base/basics.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ python一大优势在于数量丰富的库,灵活使用各种python库能帮
7878
专业素养
7979
----------
8080
公司做项目不是自己过家家,需要你具备写文档,注释,单元测试的能力。如果你现在还不了解一个正规python项目都有哪些组建构成,请去github克隆一份知名的代码仓库,花点时间仔细分析下它的项目结构和源代码。
81-
比如主名网站reddit代码已经开源,大部分python实现,可以参考下。另外很多著名的python库,比如requests/flask等也可以作为参考。
81+
比如著名网站reddit代码已经开源,大部分python实现,可以参考下。另外很多著名的python库,比如requests/flask等也可以作为参考。
8282

8383

8484
后端技术栈

codingstyle/codingstyle.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ update: 经验表明,TDD未必是必要的,但是单元测试是很必要的
132132

133133
还有OOP那一套:
134134

135+
* 单一职责原则(Single-Responsibility Principle)
135136
* 开闭原则(Open-Closed Principle)
136-
* 依赖倒置原则(Dependence Inversion Principle)
137-
* 接口隔离原则(Interface Segregation Principle)
138137
* 里氏代换原则(Liskov Substitution Principle)
138+
* 接口隔离原则(Interface Segregation Principle)
139+
* 依赖倒置原则(Dependence Inversion Principle)
139140
* 迪米特原则(Law of Demeter)
140141
* 合成复用原则(Composite/Aggregate Reuse Principle)
141-
* 单一职责原则(Single-Responsibility Principle)
142142

143143

144144
python代码坏味道(新手经常犯的错误)
@@ -151,10 +151,11 @@ python代码坏味道(新手经常犯的错误)
151151
- 变量名乱起,看不出类型,加重理解负担。我在想是不是动态语言用匈牙利命名法要好一些
152152
- 不遵守pep8,没有pylint检测,打开代码一堆语法警告,老子的编辑器满眼都是warnning,编辑器用不好就老老实实用pycharm,用编辑器就老老实实装好语法检测和pylint检测插件,没有插件请考虑换一个editor
153153
- 没有单元测试,不知道怎么写测试(print大法好?)。没有一点专业精神,或许和python大部分都是自学的业余选手有关。
154-
- 超长函数,没有复用和拆分,我智商低,不能理解好几屏都翻不完的,见谅。这么长居然还tm能工作,牛逼
154+
- 超长函数,没有复用和拆分,抱歉我智商低,不能理解好几屏都翻不完的,见谅。这么长居然还tm能工作,牛逼(我发现越是新手写的代码越难理解)
155155
- 到处print,debug的时候加上,上线再删除(累不累亲?),logging模块很受冷落
156156
- 上来就try/except了,把异常都捕获了,吞掉异常导致排错困难
157157
- 没注意可变类型和非可变类型,传入可变类型并在函数里修改了参数,坑。。。
158+
- 滥用 `(*args, **kwargs)` 导致函数接口模糊,有类似接口应该明确用docstring写明参数。
158159
- 没有逻辑分块,没有美感(这个就算了),就算不限制一行超过80列,也不能写一行写几百列吧,左右转头脑瓜子疼
159160

160161
嗯,一开始就开启pep8和pylint检测能显著提升代码质量(各种错误警告逼着你写出高智力代码)。咱写不了诗一样的代码,也不能写shǐ 一样的代码。

design/design.rst

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ Patterns》的读书笔记,涵盖大部分设计模式(力求pythonic实现)
1818

1919
先来看三种创建模式中的第一种工厂模式。
2020
解释:处理对象创建,客户端可以申请一个对象而不用知道对象被哪个class创建。可以方便地解耦对象的使用和创建。有两种实现,工厂方法和抽象工厂.
21-
### Factory
22-
Method(工厂方法):执行单独的函数,通过传参提供需要的对象的信息。通过一个demo看看例子:
21+
22+
Method(工厂方法):
23+
^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
执行单独的函数,通过传参提供需要的对象的信息。通过一个demo看看例子:
2326

2427
::
2528

@@ -57,7 +60,7 @@ Method(工厂方法):执行单独的函数,通过传参提供需要的对象
5760
return connector(filepath)
5861

5962
Abstract Factory(抽象工厂: 解决复杂对象创建问题)
60-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6164

6265
工厂方法适合对象种类较少的情况,如果有多种不同类型对象需要创建,使用抽象工厂模式。以实现一个游戏的例子说明,在一个抽象工厂类里实现多个关联对象的创建:
6366

@@ -1422,3 +1425,75 @@ Peters在2002年设计的结合了合并排序和插入排序的\ `Timsort <http
14221425
class MyClass(BaseClass, metaclass=Singleton):
14231426
pass
14241427

1428+
1429+
--------------
1430+
1431+
面向过程与面向对象
1432+
--------------------------------------
1433+
设计模式讲完了,来看看python中OOP的相关东西。笔者在经历过的两家公司见到过各种python程序员,之前的公司有python高手习惯写OOP风格的(给我很深影响),目前所在公司大部分人对python的面向对象不是很熟,写出来的基本都是过程式的。
1434+
1435+
- 过程式: 基本都是一个个函数(function)来实现功能,你给我一些参数,我对参数做出各种操作,返回需要的结果。
1436+
- 面向对象:把资源抽象成一个类,数据(data)和方法(method)的集合。在构造函数中进行数据属性的初始化,在方法中进行对象数据的各种操作。
1437+
1438+
哪种方式更好这个我暂时没有定论,编程规范也不会说强制你使用哪种风格。编码中往往没有绝对正确的,只有相对更优的,如果不好定论,那就一致,易读,易用,易维护的风格优先。
1439+
1440+
--------------
1441+
1442+
python中的抽象基类
1443+
--------------------------------------
1444+
在python中我们可以使用内置的abc(abstract base class)模块来实现抽象基类。什么时候需要一个抽象基类呢?
1445+
1446+
- 抽象基类是没法被实例化的。
1447+
- 抽象基类中定义抽象方法强制子类去实现。
1448+
1449+
::
1450+
1451+
# 为了实现这两个特性,我们可以这么写
1452+
class Base:
1453+
def foo(self):
1454+
raise NotImplementedError()
1455+
1456+
def bar(self):
1457+
raise NotImplementedError()
1458+
1459+
class Concrete(Base):
1460+
def foo(self):
1461+
return 'foo() called'
1462+
1463+
# Oh no, we forgot to override bar()...
1464+
# def bar(self):
1465+
# return "bar() called"
1466+
1467+
但是这么写依然可以实例化Base,python2.6以后引入了abc模块帮助我们实现这个功能。
1468+
1469+
::
1470+
1471+
from abc import ABCMeta, abstractmethod
1472+
1473+
class Base(metaclass=ABCMeta):
1474+
@abstractmethod
1475+
def foo(self):
1476+
pass
1477+
1478+
@abstractmethod
1479+
def bar(self):
1480+
pass
1481+
1482+
class Concrete(Base):
1483+
def foo(self):
1484+
pass
1485+
# We forget to declare bar() again...
1486+
1487+
使用这种方式如果没有在子类里实现bar方法你是没有办法实例化子类的。
1488+
1489+
* `《Abstract Base Classes in Python》 <https://dbader.org/blog/abstract-base-classes-in-python>`_
1490+
* `《http://stackoverflow.com/questions/3570796/why-use-abstract-base-classes-in-python》 <http://stackoverflow.com/questions/3570796/why-use-abstract-base-classes-in-python>`_
1491+
* `《https://docs.python.org/2/library/abc.html》 <https://docs.python.org/2/library/abc.html>`_
1492+
1493+
1494+
--------------
1495+
1496+
python中的Mixin
1497+
--------------------------------------
1498+
Mixin是为了给一个类扩充功能用的,它也没法被实例化。我们可以在Mixin类里实现一些方法给类扩充功能。你可能会问了,那为啥不直接写在
1499+
类里头,比如用@staticmethod方法(我就有这个疑问)?我的理解是这样的,为了『高内聚』。如果你用过pylint检测代码,你会发现你在写类的一个方法时,如果在写一个method时没有使用到任何self里的东西,pylint会给提示『R0201 Method could be a function [pylint]』,意思是这个方法可以可以单独写成一个函数,不必要写在类里。也就是说,只有一个类里实现的方法都是使用了self里的数据时才能成为高内聚的(我不知道我这样理解对不对)。例子:flask_login插件有个UserMixin给定义的用户类实现登录功能。

0 commit comments

Comments
 (0)