为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 python3.8+ 中自动化对象初始化

如何在 python3.8+ 中自动化对象初始化

慕斯709654 2022-07-12 10:21:50
情况我目前正在做一个小但非常可扩展的项目,我有以下结构:/|- main.py|- services   |- __init__.py   |- service1.py    |- service2.py   |- ...这些服务中的每一个都创建一个对象,它们都具有完全相同的参数,并且它们都以相同的方式使用。他们之间的区别在于内部,他们做一些事情,对于这个不重要的问题,以不同的方式做事。现在这是围绕我的代码当前如何处理它的方式:main.pyfrom services import *someObject = {} #content doesn't matter, it's always the sameserv_arr = []   # an array to hold all servicesserv_arr.append( service1.service1(someObject) ) serv_arr.append( service2.service2(someObject) )...for service in serv_arr:    # this function always has the same name and return type in each service    service.do_something()问题我的具体问题是:有没有办法通过serv_arr循环自动创建,这样,如果我添加service100.py和service101.py到包中services,我不必返回main.py并手动添加它,而是自动加载它需要?
查看完整描述

2 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

好的,基于这个想法:


奥斯汀菲尔普的回答


# services/__init__.py


from .service1 import service1

from .service2 import service2

...


services = [service1, service2, ...]


__all__ = ['services']

在这个答案中提到的工厂模式中特别公开的方法和模块的想法,我想出了一个非常hacky的解决方案,它不会使全局命名空间混乱(@Austin Philp 批评的另一件事)。


解决方案

我有了在每个模块中实现一个方法的想法,该方法除了创建所述模块的实例之外什么都不做,并且每个模块都在以下内容中提到services/__init__.py:


#services/__init__.py

from .service1 import service1

from .service2 import service2


__all__=["service1", "service2", ...]

#services/service1.py

class service1(object):

    def __init__(self, input):

        ...

...

def create_instance(input):

    return service1(input) # create the object and return it. 

然后在 main.py 中,我只是这样做(它非常hacky,但它有效)


#main.py

import services

import sys


# use the __all__ method to get module names. actually

for name in services.__all__:

    service = sys.modules[f'services.{name}'].create_instance( input )

    # do whatever with service

这样我就可以愉快地做任何需要的事情,而不会弄乱全局命名空间,但仍然可以迭代甚至单独调用模块。要添加/删除模块,我唯一需要编辑的是__all__内部变量中的另一个条目services/__init__.py。它甚至消除了对serv_arr数组的需要,因为services.__all__已经有了我感兴趣的所有名称,并且与使用的模块具有相同的长度。


查看完整回答
反对 回复 2022-07-12
?
catspeake

TA贡献1111条经验 获得超0个赞

首先,您应该真正避免使用该from xxx import *模式,因为它会使全局命名空间变得混乱。


您可以将可用服务列表添加到services/__init__.py


像这样的东西


# services/__init__.py

from .service1 import service1

from .service2 import service2

...


services = [service1, service2, ...]


__all__ = ['services']

如果这对您来说仍然过于手动,您可以遍历目录并使用importlib它们的路径导入服务。


但是,我不禁认为这个问题表明设计不好。您可能需要考虑使用类似工厂模式的东西来实例化各种服务,而不是使用大量单独的模块。实际上,如果您想对所有服务进行小幅更改,那么您将面临许多繁琐的工作。


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信