Python:告别if...else...做真正面向对象的编程
来源:互联网 发布:淘宝装修工具下载 编辑:程序博客网 时间:2024/05/03 21:48
欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/51417564
最近在给服务器做一套指令系统,大家都知道一个服务器的指令有很多,像(加金币,加道具,加经验...)
代码就像这样:
cmd = REQUEST.get("cmd", "")if cmd == "add_gold":passelif cmd == "add_item":passelif cmd == "add_exp":pass... ...else:send("cmd unknow")exit(9)
然而一个普通的游戏,指令起码也得上百,于是乎我们就拖着鼠标从头拉到尾看看if else有没有我们需要的指令。而且,如果多人维护同一个系统,比如A要加一个指令,B也要加一个指令,这个时候就会有SVN冲突的隐患。
更重要的是,python作为一门面向对象的语言,难道就只能用if else处理这种问题吗,这完全是面向过程的c语言编程方式。既然作为面向对象的语言,我们就用面向对象的方法来解决问题。
什么是面向对象:
把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)/泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派(dynamic dispatch)。也就是说,我们给每个指令构建一个对象,然后每接收一个指令的时候就直接通过这个对象去处理。每加一个指令,我们创建一个文件,构造一个对象,这样代码看起来会简洁很多,而且也不会有冲突的隐患。
问题是,怎么避免if else呢。因为有这么多指令,不用if else真的有办法解决吗?
答案是有的,我们把构造的对象自动注册到一个数据结构中,如果查到cmd在这个数据结构中,那么就直接执行这个对象的特定方法就好了,想想c++的多态就明白了。
那么现在的问题就是怎么自动注册到一个数据结构中。
我们扫描同一个目录下的所有文件,找到某一个指定基类的所有子类,然后获取一个列表。
就像下面这样:
def _get_module_files(module_dir):module_name_set = set()try:files = os.listdir(module_dir)except:print "error in generate_module_list for directory:", module_dirreturn ()for fileName in files:list = fileName.split('.')if len(list) == 2:module_name = list[0]extension = list[1]if extension in ("py", "pyc"):module_name_set.add(module_name)module_name_set.discard('__init__')return module_name_setdef _get_class_list(module, base_class):"""得到模块里面所有属于指定类子类的类"""m = __import__(module, fromlist=[''])cls_name = modulecls = getattr(m, cls_name, None)if issubclass(cls, base_class):return clsreturn Nonedef scan_classes(module_dir, base_class):"""主要功能就是扫描一个目录 , 并把下面所有python模块中属于指定类子类的类找出来"""class_dict = {}module_set = _get_module_files(module_dir)for module in module_set:clist = _get_class_list(module, base_class)if clist is None:continueclass_dict[clist.__name__] = clistreturn class_dict
我们的目录结构如下。
cmds:
--__int__.py
--add_gold.py
--add_item.py
--add_exp.py
--base_cmd.py
我们就可以写出以下代码:
from cmds.base_cmd import base_cmdmember_path = os.path.split(os.path.realpath(__file__))[0] + \cmds'class_dict = scan_classes(member_path, base_cmd)#然后我们每个类继承自base_cmd,写一个通用的接口deal_cmd.cmd = REQUEST.get("cmd", "")if cmd in class_dict:a = class_dict[cmd]()a.deal_cmd(REQUEST.__dict__['dict'])
ok,大功告成,以后每加一个指令,只需要在cmds目录增加一个**.py,继承自base_cmd,我们重写deal_cmd()方法就可以了。
对比之前与现在的两种写法,之前的写法感觉真的是弱爆了。
1 0
- Python:告别if...else...做真正面向对象的编程
- java面向对象if....else的运用
- 面向对象与IF-ElSE
- 面向对象之 if else
- 真正的“面向对象编程”
- 真正的Delphi面向对象编程(一)
- 不要if else的编程
- Python面向对象的编程
- python 面向对象的编程
- Python面向对象的编程
- python面向对象的编程
- 使用命令模式,告别if-else
- 使用面向对象技术替代switch-case和if-else
- 使用面向对象技术替代switch-case和if-else
- 真正的面向对象编程思想是怎样的?
- 多态(virtual)– 真正的面向对象编程
- Python中if/else结构的缩进
- Python的if...else...语句出错
- 2016-Q2 BUG清单
- 由逆序列的序号反推出逆序列
- C#控制RichTextBox滚动条的方法
- css绘制特殊形状
- JAVA基础笔记之初识JAVA
- Python:告别if...else...做真正面向对象的编程
- leetcode 189
- android开发中常用的快捷键
- iOS开发系列--IOS程序开发概览
- 使用orm(Sequelize) 操作 MySQL (1)
- POJ1276 Cash Machine(多重背包)
- 动态创建对象与delete 使用
- fast-rcnn/README.md翻译--适合新手
- Problem C: The Same Color