" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Python 项目代码规范

PySuper
2021-06-23 / 0 评论 / 0 点赞 / 15 阅读 / 12287 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

基础

规范

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

文档

  • 需求文档
Python规范
- 架构设计
Python规范
- 接口文档
Python规范

新式类

封装

  • 调用
# 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顺序如此,但是执行顺序是由我们的业务逻辑而定
Python规范
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()

装饰器模式

  • 闭包:内层函数返回外层函数引用
  • 装饰器:在不修改源码的情况下,增加一个额外的功能
  • 语法糖:@,在某函数定义时,用以包装函数,以达到截取控制该函数的目的

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区