马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
原文链接在这里:优雅的编程————面向对象还能这么玩
刚开始学面向对象的时候其实,我是完全不懂的。
我不懂它为什么要那么弄,我不懂它有何作用,我不懂它存在的意义
前段时间,我把一些代码重构了一遍,由于之前写的过于臃肿,看起来就像这样,由于我当初追求的是能运行就行,之前也没去管它,直到有一天我受不了了。。。
功能很简单,就是实现登录的功能。但是用了一堆if else。可读性烂的像一坨图片
直到我想起了面向对象,一切都变了
长度可能和之前差不多,但是变得优雅了,可读性更强了
我目前认为用面向对象有两个好处(鬼知道随着时间推移会有啥更深入的想法呢)
1.就是大家经常提到的,提高代码的可读性
2.人们提到的不多,但是很重要就是对开发者更加友好。
第二点,之所以提到的不多,是因为我们通常都是用别人或者是编程语言自带的方法,功能,也不需要知道是怎么实现的。
01
假设有一天我开发了一个web框架供其他开发者使用,web框架非常良心给使用者一个查看查看用户信息的自带功能,这样开发者就不用自己写了。
当然以下只是演示,真正的web框架源码比这复杂多了。
框架提供的查看用户信息源码可以这么写:myframework/userinfo.py class Check_info:
def __init__(self,username):
self.username=username
self.password =123 #去数据库里查username对应的密码
self.name=['vk']
开发者使用框架时只需要:from myframework.userinfo import Check_info
username=input('这里是开发者让用户输入用户名')
pwd=Check_info(username)
print(pwd.password)
但是这样用户可以查看其他用户的密码了这时候我们需要加入限制,把密码属性隐藏起来
加入权限限制 :__开头的属性是私有属性,不允许直接访问,开发者只能调pwd访问
class Check_info:
def __init__(self,username):
self.__password =123 #我是私有属性
self.username=username
self.name=['vk']
def pwd(self):
message='非法闯入'
if self.username in self.name:
message=self.__password
return message
else:
return message
开发者使用框架时只需要: user=Check_info('1')
print(user.pwd()) #注意看这里
问题又来了,看第二行,开发者明明想获得属性的值。
正常应该是xxx.xxx获取,但是web框架给的通过xxx.xx()函数式调用,不太符合常理,和开发者的使用习惯
这时候我们可以使用property
class Check_info:
def __init__(self,username):
self.__password =123 #我是私有属性
self.username=username
self.name=['vk']
@property #加上这个装饰器我们就可以用获取属性的方法获取了
def pwd(self):
message='非法闯入'
if self.username in self.name:
message=self.__password
return message
else:
return message
#开发者这么调
pwd=Check_info('vk')
print(pwd.pwd)
这样web框架就可以实现既检查了用户的访问权限,又给开发者一个符合习惯的接口
02
python中我们可以通过len()函数来获得给定变量的长度,无论给len的参数是字符串,列表,集合,元组,字典。都可以。想象一下可以怎么实现呢?
我们要是我们自己写一个类似与len()函数的功能,应该如何实现呢
python中有个内置方法叫做__len__()就相当于不管是什么对象,它被创建就自带一个__len__()的方法。假设我们是python语言的设计者源码可以这么写
class variable:
"""
我是一切变量规定我的子类有__len__()方法
"""
class list(variable):
def __len__():
"""
计算长度的算法
"""
class tuple(variable):
def __len__():
"""
计算长度的算法
"""
class dict(variable):
def __len__():
"""
计算长度的算法
"""
我只要是个变量,我们就继承那个variable()类
了解了python可能是如何设置内置方法的后(当然这只是可能,我也没去看python的 源码),我们自己实现它自带的len()方法就好办了。
只需这样:
def myownlen(obj):
return obj.__len__()
myownlen('我是字符串')
myownlen([1,2,3])
由于所有的obj都带有__len__()的方法,我们无需考虑它是什么类型。
但是其实可以更加简化,我们没必要都继承一个父类,只需要在写代码的时候约定,看起来差不多的东西,都有某个方法。
比如上面的,我们不管它到底是什么类型,只需要它看起来可以计算长度就给他__len__()方法。
可以这么优化,直接去掉父类,继承:class list():
def __len__():
"""
计算长度的算法
"""
class tuple():
def __len__():
"""
计算长度的算法
"""
class dict():
def __len__():
"""
计算长度的算法
"""
从规范的角度来书写代码,使他们都有同一个功能,看起来继承了相同的父类。
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
这就是鸭子类型。
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。
|