【问题标题】:How to make Class instance in main.py available in another file?如何使 main.py 中的 Class 实例在另一个文件中可用?
【发布时间】:2017-08-23 21:11:19
【问题描述】:

我在需要在另一个文件中以main.py 实例化的类中提供信息时遇到困难。描述我正在尝试做的事情的最佳方式可以在下面的流程图中看到:

您可以想象的问题是循环依赖。有没有办法在schema.pymain.py 之间创建一个接口,以便我可以传递类信息?

感谢您的宝贵时间和您能提供的任何帮助!

编辑:添加代码供参考

ws_transport.py

from autobahn.twisted.websocket import (
    WebSocketServerProtocol,
    WebSocketServerFactory,
)

from schema import schema


class WsProtocol(WebSocketServerProtocol):
  def __init__(self):
      # Code here

  def onConnect(self, request):
      # Code here

  def onMessage(self, payload, isBinary):
    # Code here


class WsProtocolFactory(WebSocketServerFactory):
  def __init__(self):
    super(WsProtocolFactory, self).__init__()
    self.connection_subscriptions = defaultdict(set)
    # Code here

  def check_events_db(self):
    # Code here

  def check_audit_log_db(self):
    # Code here

web_transport.py

import sys, os
import json

from twisted.web.resource import Resource
from twisted.web.server import Site, http

from schema import schema


class HttpResource(Resource):
  isLeaf = True

  def render_OPTIONS(self, request):
    # Code here

  def render_GET(self, request):
    # Code here

  def render_POST(self, request):
    # Code here



class LoginResource(Resource):
    isLeaf = True

    def render_OPTIONS(self, request):
      # Code here

    def render_GET(self, request):
      # Code here

    def render_POST(self, request):
      # Code here



class RefreshResource(Resource):
  isLeaf = True

  def render_OPTIONS(self, request):
    # Code here

  def render_GET(self, request):
  # Code here

  def render_POST(self, request):
    # Code here



class HttpFactory(Site):

  def __init__(self, resource):
    # Code here

schema.py

#!/usr/bin/python
import graphene
import json
import sys, os

from main import factory


class Query(graphene.ObjectType):
  # Code here


class Mutation(graphene.ObjectType):
  # Code here


class Subscription(graphene.ObjectType):
  # Code here


schema = graphene.Schema(query=Query, mutation=Mutation, subscription=Subscription)

main.py

import sys

from twisted.internet import reactor
from twisted.web.resource import Resource
from autobahn.twisted.resource import WebSocketResource

from ws_transport import WsProtocol, WsProtocolFactory
from web_transport import HttpResource, LoginResource, RefreshResource, HttpFactory


if __name__ == '__main__':
    factory = WsProtocolFactory()
    factory.protocol = WsProtocol
    ws_resource = WebSocketResource(factory)

    root = Resource()
    root.putChild("", HttpResource())
    root.putChild("login", LoginResource())
    root.putChild("refresh", RefreshResource())
    root.putChild(b"ws", ws_resource)

    site = HttpFactory(root)

    reactor.listenTCP(8000, site)

    reactor.run()

干杯,

布赖恩

【问题讨论】:

  • 您可以将对象作为参数传递给函数。
  • 您能否提供一个带有伪代码的示例,说明如何解决此问题?谢谢彼得!
  • 我不熟悉您的“流程图” - 我们可以假设箭头暗示某种通信吗?您能否在您的问题中添加文件中相关的导入语句是什么样的?
  • 是的,这是一个安全的假设。我将用一些代码编辑我原来的问题。
  • @wwii 我已经用代码 sn-ps 更新了我的原始帖子。我需要能够将 main.py 中的工厂实例导入 schema.py,以便在定义的类中可以使用此信息。

标签: python design-patterns dependency-injection software-design circular-dependency


【解决方案1】:

我知道这不一定是您需要的答案。但是我遇到了同样的问题,对我来说,这意味着我的项目结构错误。意思是 main.py 或 schema.py 做他们不应该做的事情。当然,你做了这个项目,所以你可以决定做什么,但我的意思是,也许你应该抽象更多。因为我不知道库,所以我不太明白你想用代码做什么。

一个简单的 hacky 类型的事情是创建另一个名为也许 run.py 的文件,然后将文件和依赖注入 main 导入模式或其他方式。 另一个不太好的解决方案是创建一个 init() 函数,然后在初始化其余文件后导入另一个文件,从而确保只执行一次导入。

但是所做的是从概念上检查为什么 main 需要导入(在你的情况下)模式,然后问自己这真的是 main.py 应该做的。如果例如您的主要需要为所有其他模块提供模板,那么为什么不创建 templates.py 或 modules.py?或者在我的情况下更好的是创建一个总线系统。这可以允许模块仅在需要时共享所需的数据并公开通用 api。当然,这只有在您只分享信息时才有意义。

总结:通常当应用程序设计良好时,您永远不会遇到循环导入。当你这样做时,这表明你应该重新考虑如何构建你的程序。

【讨论】:

  • 感谢@Pixdigit 的出色回复。总之,我认为您很好地解释了我遇到的问题是由于设计问题。需要一个 API 来在我想要的时候分享我想要的信息,我将处理这个问题,并在解决这个问题后报告!再次感谢
【解决方案2】:

对于 Python 函数,您可以这样做。

def functionInSchema(objectParameter):
    # Add in code

这将使您能够从main.py 文件中访问对象。 要访问属性/方法,请使用参数名称、点和属性/函数名称。

def functionInSchema(objectParameter):
     attribute = objectParameter.attribute
     objectParameter.method()

然后在main.py 中将Class 实例(Object)作为参数传递。

objectInMain = Class(param1, param2)

functionInSchema(objectInMain)

如果您需要访问schema.py 中的类,您可以使用以下导入。

from main.py import ClassName

希望对您有所帮助!祝你好运!

【讨论】:

    猜你喜欢
    • 2015-02-16
    • 2017-02-28
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 2014-02-11
    • 1970-01-01
    相关资源
    最近更新 更多