在金字塔中的非请求上下文中检索应用程序配置设置

2024-10-03 11:23:16 发布

您现在位置:Python中文网/ 问答频道 /正文

在我正在构建的金字塔应用程序(称为pyplay)中,我需要检索我在其中的应用程序设置开发.ini. 问题是我试图获取该设置的地方无法访问请求变量(例如,在模块文件的顶层)。在

所以,在看了文档中的这个例子之后:http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/configuration/django_settings.html我开始做一些非常简单的硬编码的事情,只是为了让它正常工作。 自从我开发.ini有这个部分:[应用程序:主],那么我尝试的简单示例如下:

from paste.deploy.loadwsgi import appconfig
config = appconfig('config:development.ini', 'main', relative_to='.')

但应用程序拒绝启动并显示以下错误:

^{pr2}$

所以,我想也许我应该把“pyplay”改为“main”,我继续了,但是我得到了一个错误:

LookupError: No section 'pyplay' (prefixed by 'app' or 'application' or 'composite' or 'composit' or 'pipeline' or 'filter-app') found in config ./development.ini

在这一点上,我有点卡住,我不知道我做错了什么。有人能帮我做这个吗?在

提前谢谢!在

编辑:以下是我的开发.ini文件(注意皮什。帕兰是我要获取的设置):

###
# app configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###

[app:main]
use = egg:pyplay

pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en_US.utf8
pyramid.includes =
    pyramid_debugtoolbar
    pyramid_tm

sqlalchemy.url = mysql://user:passwd@localhost/pyplay?charset=utf8

# By default, the toolbar only appears for clients from IP addresses
# '127.0.0.1' and '::1'.
debugtoolbar.hosts = 127.0.0.1 ::1

pish.theparam = somevalue

###
# wsgi server configuration
###

[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543

###
# logging configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###

[loggers]
keys = root, pyplay, sqlalchemy

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_pyplay]
level = DEBUG
handlers =
qualname = pyplay

[logger_sqlalchemy]
level = INFO
handlers =
qualname = sqlalchemy.engine
# "level = INFO" logs SQL queries.
# "level = DEBUG" logs SQL queries and results.
# "level = WARN" logs neither.  (Recommended for production systems.)

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

Tags: orpyramidapp应用程序httpdocssqlalchemymain
3条回答

步骤1:创建一个singleton类,比如在一个文件xyz_文件中 在

class Singleton:
def __init__(self, klass):
    self.klass = klass
    self.instance = None
def __call__(self, *args, **kwds):
    if self.instance == None:
        self.instance = self.klass(*args, **kwds)
    return self.instance

@Singleton
class ApplicationSettings(object):
   def __init__(self, app_settings=None):
       if app_settings is not None :
           self._settings = app_settings
   def get_appsettings_object(self):
       return self

   def get_application_configuration(self):
       return self._settings

第2步:在“\uuuinit_uuy.py”中

^{pr2}$

步骤3:您应该能够访问代码的任何部分。在

  from xyz_file import ApplicationSettings
  app_settings = ApplicationSettings().get_application_configuration()

基本上,如果您没有访问请求对象的权限,那么您在金字塔中“偏离轨道”。为了以金字塔的方式进行工作,我们制作组件并确定它们在金字塔生命周期中的位置,并且它们应该始终能够直接访问注册表(ZCA)和请求中的一个或两个。在

如果您所做的不适合请求生命周期,那么它可能是应该在服务器启动时实例化的,通常是在您的init.py中生成并填充配置器(我们对注册表的访问)。不要害怕以后使用注册表允许其他组件获取“伪全局”的东西。因此,您可能想为您的东西创建某种工厂,在启动代码中调用该工厂,也许将对注册表的引用作为参数传入,然后将对象附加到注册表。如果您的组件需要与请求生命周期代码接口,请为其提供一个将request作为参数的方法。稍后,这个对象需要的任何东西都可以从注册表中获取,这个对象需要的任何东西都可以通过注册表或请求来完成。在

你完全可以使用另一个答案中的黑客攻击来获取当前的全局注册表,但需要这样做是一种代码气味,你可以找到一个更好的设计来消除它。在

服务器启动代码中的伪代码示例:

# in in the init block where our Configurator has been built
from myfactory import MyFactory
registry.my_component = MyFactory(config.registry)
# you can now get at my_component from anywhere in a pyramid system

您的组件:

^{pr2}$

金字塔视图是这样工作的。它们实际上是请求和上下文的ZCA多适配器。它们的工厂在注册表中注册,然后当视图查找过程启动时,工厂将实例化一个视图作为param传入请求。在

在金字塔中很难做到的原因是,模块级设置总是一个坏主意。这意味着每个进程只能以一种方式使用模块(不同的代码路径不能以不同的方式使用库)。:-)

对于不能访问request对象的一种方法是,至少在函数调用后面隐藏全局,这样每个线程的全局变量都是不同的(基本上是每个请求)。在

def get_my_param(registry=None):
    if registry is None:
        registry = pyramid.threadlocals.get_current_registry()
    return registry.settings['pyplay.theparam']

相关问题 更多 >