Python 如何以干燥方式分解此py文件?

Python 如何以干燥方式分解此py文件?,python,dry,Python,Dry,在Flask应用程序的业务逻辑上下文中,我正在编写一个类的大量“定义”实例,将它们放入一个列表中,并在需要时导入该列表。在构建它的外部,列表被视为静态的 简化示例: 定义。py: from my_object import MyObject definition_registry = list() # team 1, widget 1 definition _definition = MyObject() _definition.name = "team 1 widget 1&qu

在Flask应用程序的业务逻辑上下文中,我正在编写一个类的大量“定义”实例,将它们放入一个列表中,并在需要时导入该列表。在构建它的外部,列表被视为静态的

简化示例:

定义。py

from my_object import MyObject

definition_registry = list()

# team 1, widget 1 definition
_definition = MyObject()
_definition.name = "team 1 widget 1"
_definition.coercer = str
definition_registry.append(_definition)

# team 1, widget 2 definition
_definition = MyObject()
_definition.name = "team 1 widget 2"
_definition.coercer = int
definition_registry.append(_definition)

# team 2, widget 1 definition
_definition = MyObject()
_definition.name = "team 2 widget 1"
_definition.coercer = float
definition_registry.append(_definition)
from definitions import definition_registry

if __name__ == '__main__':
    print(definition_registry)
my\u object.py:

class MyObject:
    def __init__(self):
        self.name = "unnamed"
        self.coercer = int

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
[MyObject instance: team 1 widget 1 / <class 'str'>, MyObject instance: team 1 widget 2 / <class 'int'>, MyObject instance: team 2 widget 1 / <class 'float'>]
main.py

from my_object import MyObject

definition_registry = list()

# team 1, widget 1 definition
_definition = MyObject()
_definition.name = "team 1 widget 1"
_definition.coercer = str
definition_registry.append(_definition)

# team 1, widget 2 definition
_definition = MyObject()
_definition.name = "team 1 widget 2"
_definition.coercer = int
definition_registry.append(_definition)

# team 2, widget 1 definition
_definition = MyObject()
_definition.name = "team 2 widget 1"
_definition.coercer = float
definition_registry.append(_definition)
from definitions import definition_registry

if __name__ == '__main__':
    print(definition_registry)
输出:

class MyObject:
    def __init__(self):
        self.name = "unnamed"
        self.coercer = int

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
[MyObject instance: team 1 widget 1 / <class 'str'>, MyObject instance: team 1 widget 2 / <class 'int'>, MyObject instance: team 2 widget 1 / <class 'float'>]
这是更好的,但它仍然闻起来,因为

  • 来自。。。导入定义
    在同一文件中重复
  • 必须为每个定义文件重复导入MyObject
您的安装程序使用率为

import MyObject

# Put your specifications into a readable list
widget_specs = [
    ["Team 1 widget 1", str],
    ["Team 1 widget 2", float],
    ...
]
for name, coercer in widget_specs:
    _ = MyObject(name, coercer)
然后访问所需小部件对象的所有实例


这能解决问题,或者至少能让你离得足够近吗?

我会这样安排:

myobject.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
定义.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)

有几种方法可以做到这一点。搜索实现插件的代码。以下是一种方法:

按如下方式编写代码:

/myproject
    main.py
    my_object.py
    definitions/
        __init__.py
        team_1.py
        team_2.py
main.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
这基本上与您的代码相同,有一些额外的代码来显示正在发生的事情

import sys

before = set(sys.modules.keys())

import definitions

after = set(sys.modules.keys())

if __name__ == '__main__':
    print('\nRegistry:\n')
    for item in definitions.registry:
        print(f"    {item}")
    print()

    # this is just to show how to access things in team_1
    print(definitions.team_1.foo)
    print()

    # this shows that the modules 'definitions', 'definitions.team_1',
    # and 'definitions.team_2' have been imported (plus others)
    print(after - before)
my_object.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
正如其他人指出的,
MyObject
可以将名称和强制器作为参数 到
\uuuu init\uuuu()
,注册表可以是一个类变量,其注册由
\uuuu init\uuuuu()
处理

定义/init.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
这是技术的核心。导入包时,
\uuuuu init\uuuuuuu.py
将运行,例如
main.py
具有
导入定义时。主要思想是使用
pathlib.Path.glob()
查找所有名为
team.*
的文件,并使用
importlib.import\u module()导入它们:

定义/team_1.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
需要导入
MyObject
才能创建实例。显示模块中可以实例化多个
myObject
,以及其他内容

import pathlib
from my_object import MyObject

file_name = pathlib.Path(__file__).stem

print(f"        in {__package__}.{file_name}")

# assign the object (can get it through registry or as team_1.widget_1
widget_1 = MyObject("team 1 widget 1", str)

# don't assign the object (can only get it through the registry)
MyObject("team 1 widget 2", int)

# can define other things too (variables, functions, classes, etc.)
foo = 'this is team_1.foo'
定义/team_2.py

class MyObject:
    def __init__(self, name="unnamed", coercer= int):
        self.name = name
        self.coercer = coercer

    def __repr__(self):
        return f"MyObject instance: {self.name} / {self.coercer}"
# just done for 2 items - If you want to distribute those definitions, 
# you can define each element in a single file
teams = [{"name": "team 1 widget 1", "coercer": str}, {"name": "team 1 widget 2", "coercer": int}]

definition_registry = [MyObject(**element) for element in teams]
from my_object import MyObject

print(f"        in {__package__}.{__file__}")

# team 2, widget 1 definition
MyObject("team 2 widget 1", float)
其他东西

如果您不能更改
MyObject
,也许您可以对其进行子类化,并在
team_1.py
中使用子类,等等

或者,定义一个
make\u myobject()
factory函数:

def make_myobject(name="unknown", coercer=str):
    definition = MyObject()
    definition.name = name
    definition.coercer = coercer
    registry.append(definition)
    return definition
然后
team_1.py
看起来像:

from my_object import make_myobject

make_myobject("team 1 widget 1", int)

....
最后,
int
str
,以及其他类型、类等可以按名称查找。因此,在您的简化示例中,
MyObject()
make\u MyObject()
可以使用
强制器的名称进行查找

import sys

def find_coercer(name):
    """Find the thing with the given name. If it is a dotted name, look
    it up in the named module. If it isn't a dotted name, look it up in
    the 'builtins' module.
    """
    module, _, name = name.strip().rpartition('.')

    if module == '':
        module = 'builtins'

    coercer = getattr(sys.modules[module], name)

    return coercer

谢谢,但我的问题是将
definitions.py
分解为多个文件。谢谢,但我的问题是将
definitions.py
分解为多个文件。