3

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

因此,在查看文档中的这个示例之后:http: //docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/configuration/django_settings.html我开​​始做一些非常简单和硬编码的事情,只是为了让它工作。由于我的 development.ini 有这个部分:[app:main],那么我尝试的简单示例如下:

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

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

ImportError: <module 'pyplay' from '/home/pish/projects/pyplay/__init__.pyc'> has no 'main' attribute

所以,我想也许我应该放 '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

在这一点上我有点卡住了,我不知道我做错了什么。有人可以帮我看看如何做到这一点吗?

提前致谢!

编辑:以下是我的 development.ini 文件的内容(注意 pish.theparam 是我想要获取的设置):

###
# 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
4

3 回答 3

3

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

无法访问请求对象的一个​​技巧是至少将全局隐藏在函数调用后面,以便每个线程的全局可以不同(基本上是每个请求)。

def get_my_param(registry=None):
    if registry is None:
        registry = pyramid.threadlocals.get_current_registry()
    return registry.settings['pyplay.theparam']
于 2013-10-14T17:00:53.177 回答
1

第 1 步:在文件 xyz_file 中创建一个单例类

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 步:在“__ init__.py”中

def main(global_config, **settings):
  ....
  .......
  app_settings = ApplicationSettings(settings)

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

  from xyz_file import ApplicationSettings
  app_settings = ApplicationSettings().get_application_configuration()
于 2015-09-23T15:31:47.767 回答
0

基本上,如果您无权访问请求对象,那么您在 Pyramid 中就“脱轨”了。为了以 Pyramid 方式做事,我们制作组件并确定它们在 Pyramid 生命周期中的位置,并且它们应该始终可以直接访问注册表(ZCA)和请求中的一个或两个。

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

您完全可以使用其他答案中的 hack 来获取当前的全局注册表,但是需要这样做是代码异味,您可以找到更好的设计来消除它。

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

# 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

你的组件:

class MyFactory(oject):
    def __init__(self, registry):
        # server start up lifecycle stuff here    
        self.registry = registry

    def get_something(self, request):
        # do stuff with the rest of the system
        setting_wanted = self.registry.settings['my_setting']

金字塔视图以这种方式工作。它们实际上是请求和上下文的 ZCA 多适配器。他们的工厂在注册表中注册,然后当视图查找过程开始时,工厂实例化一个视图作为参数传递请求。

于 2015-09-26T19:00:32.157 回答