繁体   English   中英

yaml.constructor.ConstructorError: 在构建 Python 对象时无法在模块“__main__”中找到“module_name”

[英]yaml.constructor.ConstructorError: while constructing a Python object cannot find "module_name" in the module '__main__'

我尝试从 file.yml 构造一些类

你可以看到 priters.yml 的结构如下:

--- !Station
recipients:
        - &first_phone ['Max']
        - &second_phone ['Anna', 'Alisa']
obj:
        - &first !!python/object:__main__.Nokia
                model: Nokia_8800
                recipients: *first_phone
        - &second !!python/object:__main__.Apple
                model: iPhone4
                recipients: *second_phone
spam_station: !station
    Nokia: *first
    Apple: *second

类构造函数出现在 spam_station.py 中

from abc import ABC, abstractmethod
from typing import Union
from yaml import YAMLObject, load

class AbstrackPhone(ABC):
    @abstractmethod
    def send_message(self, message):
        pass

class Nokia(AbstrackPhone):
    def __init__(self):
        self.model = None
        self.recipients = []

    def send_message(self, message):
        for recipient in self.recipients:
            print(f"Hi {recipient} i'm {self.model}. {message}")


class Apple(AbstrackPhone):
    def __init__(self):
        self.model = None
        self.recipients = []

    def send_message(self, message):
        for recipient in self.recipients:
            print(f"Hi {recipient} i'm {self.model}. {message}")


class ConstructStation(YAMLObject):
    yaml_tag = u'!Station'

    @classmethod
    def from_yaml(Class, loader, node):
        def get_satation(loader, node):
            data = loader.construct_mapping(node)
            station = Class.Station()
            station.add_phones(data.values())
            return station

        loader.add_constructor(u"!station", get_satation)
        return loader.construct_mapping(node)['spam_station']

    class Station():

        def __init__(self):
            self.senders = []

        def add_phones(self, phones: Union[list, str]):
            self.senders.extend(phones)

        def send_message(self, message, **kwargs):
            for sender in self.senders:
                sender.send_message(message, **kwargs)

def station():
    with open('../yaml_config/printers') as file:
        spam_station = load(file)
    return spam_station

if __name__ == "__main__":
    station().send_message('Good luck!!!')

我已经尝试在 sender.py 中导入并使用“站”:

from station.spam_station import station

if __name__ == "__main__":
    station().send_message('Good luck!!!')

当我运行 spam_station.py 时,没问题:

Hi Max i'm Nokia_8800. Good luck!!!
Hi Anna i'm iPhone4. Good luck!!!
Hi Alisa i'm iPhone4. Good luck!!!

当我运行 sender.py 时,出现错误:

yaml.constructor.ConstructorError: while constructing a Python object
cannot find 'Nokia' in the module '__main__'
  in "../yaml_config/printers", line 7, column 11

如何解决这个问题呢? 请告诉我,将 python 对象配置为 yaml 的好做法是什么。 谢谢!

问题是,当您执行sender.py ,该文件(而不是spam_station.py )是__main__

最好的解决方案可能是避免依赖 YAML 文件中的导入路径。 你已经用Station做到了,所以你也可以简单地在其他类上做到这一点:

class Nokia(AbstrackPhone, YAMLObject):
    yaml_tag = u"!Nokia"
    def __init__(self, model = None, recipients = []):
        self.model = model
        self.recipients = recipients

    def send_message(self, message):
        for recipient in self.recipients:
            print(f"Hi {recipient} i'm {self.model}. {message}")

现在您可以在 YAML 文件中使用!Nokia而不是!!python/object:__main__.Nokia Apple类也是如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM