利用反射实验工厂模式

  • python反射函数
  • 利用反射实现工厂模式

一.python反射函数

PYTHON版本为2.7

1.import(name[, globals[, locals[, fromlist[, level]]]])

name:包名
globals:未用上,用上后补充
locals:未用上,用上后补充
fromlist: from warehouse.models import YWWarehouse 中的 YWWarehouse
level:默认0,未用上,用上后补充

2.getattr(object, name[, default])

object -- 对象。
name -- 字符串,对象属性。
default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。

3.setattr(object, name, value)

object -- 对象。
name -- 字符串,对象属性。
value -- 属性值。

4.delattr(object, name)

object -- 对象。
name -- 必须是对象的属性。

二.利用反射编写工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量

现在有这样一个文件夹
在这里插入图片描述
DGWarehouse与YWWarehouse里有很多的类,DGWarehouse内容如下

我们需要根据不同的条件创建不同的对象,一般情况下我们可以用ifelse来判断并创建对象,但是条件多了话就出现上百个ifelse,这是很不合理的,所有我们就要用到了工厂模式.

1.新建一个工厂类

class warehouseFactory(object):
    """
    仓库工厂
    """
    WAREHOUSE = {
        'YW': 'warehouse.models.YWWarehouse',
        'DG': 'warehouse.models.DGWarehouse'
    }

    YW = {
        'YW':'BaseYWwarehouse',
        '一号区': 'YWFirstLocation',
        '二号区': 'YWSecondLocation',
        '三号区': 'YWThirdLocation',
        '四号区': 'YWFourthLocation',
        '五号区': 'YWFivethLocation',
        '六号区': 'YWSixthLocation',
        '七号区': 'YWSeventhLocation',
        '平销一区': 'YWPingXiaoOneLocation',
        '平销二区': 'YWPingXiaoTwoLocation',
        '新品一区': 'YWNewProductionOneLocation',
        '新品二区': 'YWNewProductionTwoLocation',
        '新品三区': 'YWNewProductionThreeLocation',
        '呆滞区': 'YWBulkProductionLocation',
    }

    DG = {
        'DG': 'BaseDGwarehouse',
        '一号区': 'DGFirstLocation',
        '二号区': 'DGSecondLocation',
        '三号区': 'DGThirdLocation',
        '四号区': 'DGFourthLocation',
        '五号区': 'DGFivethLocation',
        '六号区': 'DGSixthLocation',
        '七号区': 'DGSeventhLocation',
        '八号区': 'DGEighthLocation',
        '九号区': 'DGNinthLocation',
        '十号区': 'DGTenthLocation',
        '十一号区': 'DGEleventhLocation',
        '十二号区': 'DGTwelfthLocation',
    }
        def __init__(self,warehouse_name,warehouse_location=''):
        """
        初始化仓库
        :param warehouse: 仓库名 字符串
        :param location:  库位名 字符串
        """
        self.warehouse_name = warehouse_name
        self.warehouse_location = warehouse_location

这个工厂类配置所有仓库所在文件,还有对应仓库所有的库位
接下来我要根据传入仓库名与库位名动态创建对象

    def getWarehouse(self):
        """
        返回仓库对象
        :return:
        """
        #获取仓库,导入包
        if hasattr(self,self.warehouse_name):
            #获取包路径
            path = self.WAREHOUSE[self.warehouse_name]
            #获取文件名
            package = path.split('.')[-1]
            #导入文件
            imp = __import__(path,fromlist=[package])
            # 获取库位,返回对象
            if self.warehouse_location:
                #根据传入的库位获取类名
                location = getattr(self,self.warehouse_name)[self.warehouse_location]

            else:
                #没有的话就取第一个总仓库
                location = getattr(self,self.warehouse_name)[self.warehouse_name]
            #创建对象    
            warehouse = getattr(imp,location)()

            return warehous

几十行代码就能解决大量的ifelse,然后新增类,就只要在配置字典上添加对应的类名就可以了,符合软件设计的开闭原则.

猜你喜欢

转载自blog.csdn.net/makegame88/article/details/84653422
今日推荐