python模块和类的通用转换规则(2),三步转oo
介绍模块和类怎么互相转换,不谈面向对象的继承 封装 多态等特点。
一个person_module模块,有人的基本属性和功能。
person_module.py如下
- # coding=utf8
- name = '小明'
- eye_color = 'blue'
- age = 10
- def get_eye_color():
- return name + '的眼睛颜色是: ' + eye_color
- def show_age():
- print name + '的年龄是: ' + str(age)
- def grow():
- print name + ' 增长一岁了'
- globals()['age'] += 1 ##这里要注意一定要这样写活着声明age是全局的,否则会出错
- print globals()['age']
- show_age()
- if __name__ == "__main__":
- print get_eye_color()
- show_age()
- grow()
现在假如这个模块是别人写的,我们拿来用,现在我们要把名字换成小红,眼睛颜色换成黑色,年龄换成15岁,成长函数,一次增加两岁
那我们就需要修改别人的源码文件了,可能改着改着改错了,不知道怎么复原了。
那就import这个模块吧。
xiaohong.py
- # coding=utf8
- import person_module as p
- from person_module import *
- p.name = '小红'
- p.age = 14
- p.eye_color = 'black'
- def grow():
- print p.name + ' 增长一岁了'
- p.age += 2
- print p.age
- show_age()
- p.grow = grow
- print p.get_eye_color()
- show_age()
- p.grow() # 直接grow()也可以
可以看到属性被替换了,连增长函数也被替换了,一次增长两岁。
这就是给模块打猴子补丁了,这样写很别扭的实现了模块继承,类似于类继承。
希望把这个模块转换成类,oop编程。
模块和类的转换规则是:
1、模块级降为类
2、全局变量改成实例属性,全局的不会被改变的变量类似于那种const的,可以写成类属性(减少点内存存储可以)。
3、然后把函数改成方法。方法是类里面的,函数是模块里面的。
看person.py
- # coding=utf8
- class Person(object):
- def __init__(self, name, age,eye_color):
- self.name = name
- self.eye_color = eye_color
- self.age = age
- def get_eye_color(self):
- return self.name + '的眼睛颜色是: ' + self.eye_color
- def show_age(self):
- print self.name + '的年龄是: ' + str(self.age)
- def grow(self):
- print self.name + ' 增长一岁了'
- self.age += 1
- self.show_age()
- if __name__ == "__main__":
- xiaohong = Person('小红', 14, 'black')
- print xiaohong.get_eye_color()
- xiaohong.show_age()
- xiaohong.grow()
这样做了之后,统一通过self就能访问age name了,改变age也不需要蛋疼的声明一下age是全局的那个了。
就这样三个步骤,就能把面向过程的模块改成面向对象了。
最主要是前面那种导入模块的方法,打补丁很麻烦,那例子还只是实现小红,如果要实现小黄、小花,那就复杂了。如果使用oop,类的多个实例就自然多了,也简单直观。
如果要改变grow方法,继承一下就行了,改成这样
大部分入门都是第一种写法,毕竟py编程太自由了,可以一条条从上往下指令平铺,也可以抽成函数,也可以oop。用py会长期形成了懒惰的写法用前面第一种,但复用性真的比oop差很多,总体看起来也low一些。比如多个过程需要共享中间状态时,单纯的使用函数会写得很糟糕,这时候就应当使用类,否则要么搞全局变量要么频繁的return频繁的传参,为什么反对模块编程,就是因为模块难以初始化赋值,模块的多实例难以搞,类能很好解决。非oop一些设计模式很难用上。也有人坚决说他不需要oop,说不需要那是没认真对比过,或者压根不了解,只是死记硬背类的 继承 封装多态这几个词语,并没有实践对比过。还有的说python里面一切皆是对象,所以他写的就是oop,没错,那样仅限于有int 类 str类 字典类 或者导入了三方库后有了Request类 Response类,selenim的webdriver的Chrome类 Firefox类,仅限于此啊,没有自己的类,python一切皆对象(在py里面随便写个 a = 5,a就可以说是int类的一个实例了,py是面向对象的极致,甚至比java还极致,java里面的int a = 5,a是基本数据类型,要用到一些必要的方法支持还的把a转成Interger类的对象,php里面的字符串操作是由函数完成的,php的小写字符串转大写是 strtoupper("Hello WORLD!"),py的小写转大写是“Hello WORLD!”.uper(),object.func()和func(object)就是op和oo的区别。除了py里面的例如__len__用,len(str1)来获取长度,但这种是通过反射完成,也可以用str.__len__(),len(str)形式上看起来不那么oo。)虽然py一切皆对象,py是最极致的面向对象,但这不代表随便写就是oop编程了。三方库为什么调用的那么爽,那是人家oop了,人家三方库全写函数,调用起来就知道什么叫痛苦了,都不知道应该调用哪些函数来处理那个对象了。这都什么年代了,还对oop持怀疑和反对态度。php py js es6都是在慢慢的后来加入类的概念,难道发明语言的人会比我们差吗。
必须对py的oop非常熟悉,才能开始学习java。不然的是肯定看不懂java。
一个模块内可以多个类,类可以把模块分割裂更小的模块组织单元。oo大量实例化时候需要占用更多的内存,性能是比op差。如果担心oo性能比op差,那一样可以适当地写类里面的静态方法或者类方法,无需实例化,常用的工具方法不要全写成实例方法,干个啥都要实例化,该用静态就要用静态。
这是一些体会,po和oo每次写时候顺便脑补一下,另一种大概是怎么样的。全局变量太多,多个函数操作一个东西,就可以想下oop,oo能消灭全局,平铺式的代码适合简单脚本,或者快速验证和测试或者顶层脚本,但如果是作为被导入模块,再用这种写法,模块里面大量写非final类型的全局变量是很脑残的低级入门写法。模块级的po是拿个源码脚本,到处去修改一些变量的值,例如age name什么的。oo是对数据和方法的封装,op是函数和传参分离在两个地方。
以上为简单例子,oop的进阶是设计模式。
如果不是按照这种写人的方式,全局变量加函数的面向过程写法,而是完全的没有全局变量一步步return和传参的,执行三步走那就是只有class外壳的类,仍然是一个面向过程的类,需要再加一步。
关于pythoh面向过程开发人员三步转面向对象的补充,再加一步,四步走战略。转面向对象也可以有固定公式。
python模块和类的通用转换规则(2),三步转oo的更多相关文章
- 孤荷凌寒自学python第四十六天开始建构自己用起来更顺手一点的Python模块与类尝试第一天
孤荷凌寒自学python第四十六天开始建构自己用起来更顺手一点的Python模块与类,尝试第一天 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 按上一天的规划,这是根据过去我自学其它编程语 ...
- Python模块和类.md
模块的定义 代码的层次结构 对于python的层次结构一般为包->模块 包也就是文件夹,但是文件夹下必须有文件"init.py"那么此文件夹才可以被识别为包."in ...
- python 有class外壳不一定是oop,到底怎么oo?
1.继承 封装 多态是面向对象的三大特点,当年在考c++期末考试时候这三个特点还是作为填空题出现的. 而且老师也反复唠叨继承封装 多态,这三个词语是背得滚瓜烂熟了,但因为不是特别专业的计算机科班,学得 ...
- python 多线程编程之threading模块(Thread类)创建线程的三种方法
摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...
- python之模块、类、对象
模块就像字典 字典是python中唯一映射关系,它用一个事物对应另外一个事物,也就是所谓的key->value. 模块包含一些变量和函数,可以导入,并且可以用点(·)来操作访问变量和函数. 记住 ...
- Python第十一天 异常处理 glob模块和shlex模块 打开外部程序和subprocess模块 subprocess类 Pipe管道 operator模块 sorted函数 os模块 hashlib模块 platform模块 csv模块
Python第十一天 异常处理 glob模块和shlex模块 打开外部程序和subprocess模块 subprocess类 Pipe管道 operator模块 sorted函 ...
- 【Python基础】lpthw - Exercise 40 模块、类和对象
一. 模块(module) 模块中包含一些函数和变量,在其他程序中使用该模块的内容时,需要先将模块import进去,再使用.操作符获取函数或变量,如 # This goes in mystuff.py ...
- python模块之HTMLParser(原理很大程度上就是对类构造的熟练运用)
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python模块之HTMLParser(原理很大程度上就是对类构造的熟练运用) import HTMLPar ...
- python附录-builtins.py模块str类源码(含str官方文档链接)
python附录-builtins.py模块str类源码 str官方文档链接:https://docs.python.org/3/library/stdtypes.html#text-sequence ...
随机推荐
- CentOS 7 下 RabbitMQ 集群搭建
环境 10.0.0.20 node1 10.0.0.21 node2 10.0.0.22 node3 搭建(在所有节点执行) 添加EPEL源 [root@node1 ~]# rpm -Uvh http ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) C. Bear and Different Names 贪心
C. Bear and Different Names 题目连接: http://codeforces.com/contest/791/problem/C Description In the arm ...
- 使用 IntraWeb (36) - TIWServerControllerBase
每个应用须有且只有一个 Server Controller. TIWServerControllerBase 所在单元及继承链: IWServerControllerBase.TIWServerCon ...
- oracle索引原理(b-tree,bitmap,聚集,非聚集索引)
B-TREE索引 一个B树索引只有一个根节点,它实际就是位于树的最顶端的分支节点. 可以用下图一来描述B树索引的结构.其中,B表示分支节点,而L表示叶子节点. 对于分支节点块(包括根节点块)来说,其所 ...
- C#获取类名为Internet_Explorer_Server控件的内容
为了让大家都能够使用demo,我以IE为测试对象,另外为了突出重点,所以如何获取窗口句柄我就不做演示了(不清楚的童鞋,可以去Google下哈),句柄值我使用spy++获得 大家可以下载demo(附:s ...
- PL/SQL中复制中文再粘贴出现乱码问题的解决【转】
前不久!我对我的windowsxp做了一番大规模的设置:包括区域.系统.网络等方面的,结果当我设置完成以后,发现如果我从一些软件上复制内容到记事本里面会出现乱码,而且如果复制到word里面也不能够正常 ...
- JAVA SSH 框架介绍(转)
转载自:http://www.admin10000.com/document/150.html SSH 为 struts+spring+hibernate 的一个集成框架,是目前较流行的一种JAVA ...
- .NET 并行编程——任务并行
本文内容 并行编程 任务并行 隐式创建和运行任务 显式创建和运行任务 任务 ID 任务创建选项 创建任务延续 创建分离的子任务 创建子任务 等待任务完成 组合任务 任务中的异常处理 取消任务 Task ...
- sqlite3命令行查看中文乱码问题解决
SQLite库包含一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令.我们通过程序创建的数据库一般位于/data/data/程序db设置的content类 ...
- WCF兼容WebAPI输出Json格式数据,从此WCF一举两得
问题起源: 很多时候为了业务层调用(后台代码),一些公共服务就独立成了WCF,使用起来非常方便,添加服务引用,然后简单配置就可以调用了. 如果这个时候Web站点页面需要调用怎么办呢? 复杂的XML , ...