基础
规范
1、PEP8
- 缩进与换行 每级缩进使用四个空格
 - 限制每行的最大长度为 79 个字符
 - 空行
- 顶层函数和类之间使用两个空行
 - 类的方法之间用一个空行
 - 在函数中使用空行表示不同逻辑段落
 
 - 导入位于文件的顶部
 - 避免多余空格
 - 注释:注释要保持与时俱进,一句后面两个空格 跟注释
 - 命名规范
- 除了正常的命名规范外
 - 不要使用 大小写的 L 大写的 O 作为变量名
 - 类名首字母大写 内部类 加上前导下划线
 - 函数名应该小写 增强可读性可以使用下划线分割
 
 - 其他
- 别用 == 进行布尔值 和 True 或者 False 的比较 应该用 is
 
 
2、注释
- 单行注释
 
# 我是单行注释
- 多行注释
 
"""
多行注释1
多行注释2
多行注释3
"""
- 类说明
 
class MiniOS:
    """miniOS 操作系统"""
	
     ... ...
- 函数说明
 
class APP:
    def __init__(self, name, version, desc):
        """
        这里指明这个函数的作用
        :param name: str 软件名称
        :param version: float 版本号
        :param desc: str 文档说明
        """
3、命名风格
- 大驼峰:ClassName
 - 小驼峰:className
 - 下划线:parse_userinfo
 - 私有化:__username
 
4、高内聚、低耦合
写代码要分模块,就像搭积木,一个功能一个模块,每个模块做好一件事,不同模块之间尽量不要互相依赖
- 内聚:一个函数中,各个元素彼此结合的紧密程度(单一责任原则)
 - 耦合:各模块之间相互依赖的强弱
 
class Asd:
    def a(self, v):
        # return v + 1
        return v + 2
    def b(self, num):
        return self.a(num) + 1
    def c(self, num):
        return self.b(num) + 3
    def run(self):
        # TODO: 除run()之外的函数,尽量避免耦合,达到低耦合的目的
        # TODO:在这里完成高内聚
        aa = self.a(num)
        self.b(aa)
num = 100
AA = Asd()
print(AA.b(num))
print(AA.c(num))
5、编程思想
- POP(面向过程)
 - OOP(面向对象):属性和行为的抽象封装
 - SOA(面向服务架构)
 - AOP(面向切面):提取过程中的切面,操作
业务逻辑中的某个步骤==> 低耦合 
6、SOLID
面向对象设计和编程中几个重要编码原则
- S 单一职责原则:一个类只负责一个功能领域中的相应职责
 - O 开放/关闭原则:软件实体应开放对外扩展,而关闭修改
 - L 里氏代换原则:所有引用基类对象的地方,能够透明化的使用其子类的对象
 - I 接口隔离原则:使用多个专门的接口,而不使用但一个总接口
 - D 依赖倒转原则: 抽象不应该依赖于细节,细节应该依赖于抽象
 
变量
- 公有变量
 - 私有化:_,from xxx import yyy 时禁止导入
 - 防止冲突/重载:__
 - 魔法方法:__xx__
 
# 使用全局变量
# 注意:使用全局变量时候,修改变量的值 ==> 变量的数据类型
from comfig import SERVER_IP
# class Person(object):
class Person:
	def __init__(self, name, age, sex):
        sex =sdas
		self.name = name
		self._age = age
		self.__sex = sex
导入
# 直接导入
from xxx import yyy
import xxx
# 导入多个
from xxx import *
import xxx, yyy
from xxx import yyy, zzz
# 取别名
# 修改导入的名称时,只需要在import后面改
import das
from xxx import yyy as Y
import sys
sys.path
# 依次查找列表中的包
['',	# 首先查找当前路径
'/usr/bin',
... ....
]
# 可以通过append(),insert()方法向列表中添加
sys.path.append('/home/a/xxx')
sys.path.insert(0, '/home/a/xxx')
# import可以防止重复导入,就算导入5次,也只是第一次生效
import xx
	
# 重新导入 ==> 用来动态修改代码
from imp import reload
reload(xx)
环境
不同的项目,使用不同的包的版本
- virtualenv
 
workon NewVir
- pydev
 
cd ProjectName
- requirements.txt
 
pip freeze > requirements.txt
    
pip install -r requirements.txt
文档
- 需求文档
 
新式类
封装
- 调用
 
# def
from readfile import read_txt
    
content = read_txt(filename)
# class
from readfile import Read
content = Read.read_txt(filename)
    
from readfile.Read import read_txt
content = read_txt(filename)
- 变量
- 变量作用域
- 全局变量
 - 局部变量
 - 私有变量
 
 
 - 变量作用域
 - 隔离
@property:让方法,像属性一样访问@staticmethod:不使用形参__xx:对外隐藏属性、方法
 
class Foo:
    __x = 1  # _Foo__x = 1
    def __f1(self):  # _Foo__f1
        print('from test')
    def f2(self):
        print(self.__x)  # print(self._Foo__x)
        print(self.__f1)  # print(self._Foo__f1)
obj = Foo()
obj.f2()
print(Foo.__x)
print(Foo.__f1)
继承
- 多继承:
Python新式类MRO C3线性化算法 - MRO:方法搜索顺序
 - 重写和重载
 super()class_name.__init__方法会把每个父类全部执行一遍,而super(),全部父类方法只执行一遍- 由上可知,所有子类,统一
使用父类__init__中的参数 super(E, self)还可以直接跳到E上面的类,直接执行__init__方法MRO顺序如此,但是执行顺序是由我们的业务逻辑而定
class A:
    def __init__(self):
        print("A")
        super(A, self).__init__()
class B(A):
    def __init__(self):
        print("B")
        super(B, self).__init__()
class C(A):
    def __init__(self):
        print("C")
        super(C, self).__init__()
class D(B, C):
    def __init__(self):
        print("D")
        super(D, self).__init__()
D()
print(D.__mro__)
多态
class MiniOS:
    """miniOS 操作系统"""
    def __init__(self, name):
        self.name = name
        self.apps = []
    def __str__(self):
        return f"{self.name} install_list: {str(self.apps)}"
    def install_app(self, app):
        # 判断是否已安装
        if app.name in self.apps:
            print(f"{app.name}已安装!")
        else:
            app.install()
            self.apps.append(app.name)
class APP:
    def __init__(self, name, version, desc):
        self.name = name
        self.version = version
        self.desc = desc
    def __str__(self):
        return f"{self.name}: {self.version} {self.desc}"
    def install(self):
        print(f"正在安装{self.name}-{self.version}......")
class Pycharm(APP):
    pass
class Chrome(APP):
    def install(self):
        print("解压缩安装!")
        super(Chrome, self).install()  # 重写父类方法
linux = MiniOS("Linux")
print(linux)  # Linux install_list: []
pycharm = Pycharm("Pycharm", "1.0", "Pycharm IDE")
chrome = Chrome("Chrome", "1.1", "Chrome Install")
linux.install_app(pycharm)  # 正在安装Pycharm-1.0......
linux.install_app(chrome)  # 解压缩安装! ==> 正在安装Chrome-1.1......
linux.install_app(chrome)  # Chrome已安装!
print(linux)  # Linux install_list: ['Pycharm', 'Chrome']
设计模式
- 设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案
 - 是一种思想, 一种套路; 脱离编程语言
 - 提高代码质量
 
单例模式
确保某一个类只有一个实例存在
class Singleton(object):
	# 注意:先__new__创建一个实例对象,然后再__init__初始化实例对象
    def __init__(self):
        pass
    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):  # 反射
            Singleton._instance = object.__new__(cls)
        return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1, obj2)
# <__main__.Singleton object at 0x004415F0> <__main__.Singleton object at 0x004415F0>
工厂模式
提供一个抽象化的接口来创建一个特定类型的对象,而不是决定哪个对象可以被创建
- 使用
- 不知道用户想要创建什么样的对象
 - 当你想要创建一个可扩展的关联在创建类与支持创建对象的类之间
 
 
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
    """接口类"""
    @abstractmethod
    def pay(self, money):
        pass
class Alipay(Payment):
    def pay(self, money):
        print(f"Alipay{money}")
class WechatPay(Payment):
    def pay(self, money):
        print(f"WechatPay{money}")
class PaymentFactory:
    """工厂类"""
    def create_payment(self, method):
        if method == "alipay":
            return Alipay()
        elif method == "wechat":
            return WechatPay()
        else:
            raise TypeError(f"No such payment named {method}")
pay = Alipay()
pay.pay(12)
构造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
from abc import ABCMeta, abstractmethod
class Builder():
    # 接口
    __metaclass__ = ABCMeta
    @abstractmethod
    def draw_body(self):
        pass
class Thin(Builder):
    def draw_body(self):
        print('画瘦身体')
class Fat(Builder):
    def draw_body(self):
        print('画胖身体')
class Director():
    def __init__(self, person):
        self.person = person
    def draw(self):
        self.person.draw_body()
if __name__ == '__main__':
    # 将不同实例的引用传递到同一个构造类中,再调用不同实例的同名方法
    thin = Thin()
    director_thin = Director(thin)
    director_thin.draw()
    
    fat = Fat()
    director_fat = Director(fat)
    director_fat.draw()
适配器模式
- 使用
- 复用一些现存的类,但是接口又与复用环境要求不一致的情况
 - 将一个类的接口转换成为客户希望的另外一个接口
 
 
class Target(object):
    # 用户期望的类
    def request(self):
        print("普通请求")
class Adaptee(object):
    # 需要适配的类
    def specific_request(self):
        print("特殊请求")
class Adapter(Target):
    def __init__(self):
        self.adaptee = Adaptee()
    def request(self):
        self.adaptee.specific_request()
if __name__ == "__main__":
    # 在这里实例化的时候,实例化的是一个适配后的类
    # 有一个用户期望的方法!
    target = Adapter()
    target.request()
装饰器模式
- 闭包:内层函数返回外层函数引用
 - 装饰器:在不修改源码的情况下,增加一个额外的功能
 - 语法糖:@,在某函数定义时,用以包装函数,以达到截取控制该函数的目的
 
            
          
            
            
            
评论区