配置系统 (astropy.config
)#
介绍#
这个 astropy
组态系统的设计目的是让用户控制所使用的各种参数 astropy
或附属包,而无需深入研究源代码来进行这些更改。
备注
在4.3版之前,默认情况下会在导入时创建配置文件
astropy
。它的存在是必要的,但现在不再是这样了。
入门#
这个 astropy
通过修改配置文件可以最方便地设置配置选项。自.以来 astropy
4.3您需要创建此文件,而之前它是在导入时自动创建的 astropy
。该功能 create_config_file()
创建将所有默认值注释掉的文件::
>>> from astropy.config import create_config_file
>>> create_config_file('astropy')
此文件的确切位置可以通过以下命令获得 get_config_dir()
**
>>> from astropy.config import get_config_dir
>>> get_config_dir()
并且您应该看到您的配置目录的位置。标准方案通常将您的配置目录放在 $HOME/.astropy/config
。可以使用环境变量对其进行自定义 XDG_CONFIG_HOME
在这种情况下, $XDG_CONFIG_HOME/astropy
目录必须存在。请注意 XDG_CONFIG_HOME
来自以Linux为中心的规范(请参见 here 获取更多详细信息),但是 astropy
我将在任何操作系统上使用它作为一种更通用的方法,以了解应该在哪里写入用户特定的配置。
备注
见 Astropy的默认配置文件 此配置文件的内容。
找到配置文件后,使用您最喜欢的编辑器打开它。它应该包含您可能需要的所有部分,以及描述和接受的值类型。您可以随意编辑此内容,这些更改将在您下次启动时反映出来 astropy
。或致电 reload_config()
如果您希望立即在当前 astropy
会议::
>>> from astropy.config import reload_config
>>> reload_config()
备注
无论出于什么原因 $HOME/.astropy
目录不可访问(即 astropy
以根用户身份运行,但您不是root用户),最好的解决方案是设置 XDG_CONFIG_HOME
和 XDG_CACHE_HOME
指向目录的环境变量,并创建 astropy
每个目录里面都有。然后,配置和数据下载系统都将使用这些目录,并且从不尝试访问 $HOME/.astropy
目录。
使用 astropy.config
#
访问值#
按照惯例,配置参数位于名为 conf
在每个子包的根目录下。例如,与数据文件相关的配置参数位于 astropy.utils.data.conf
. 此对象具有用于获取和设置单个配置参数的属性。例如,获取 astropy
远程数据,do::
>>> from astropy.utils.data import conf
>>> conf.dataurl
'http://data.astropy.org/'
在运行时更改值#
如上所述,通过编辑配置文件来更改配置值的持久状态。但是,也可以通过设置的任何属性在活动的Python会话中修改值 conf
对象,或使用 set_temp()
context_manager ,只要新值符合 Item Types and Validation 。
例子#
假设您的配置文件中有一部分如下所示:
[utils.data]
# URL for astropy remote data site.
dataurl = http://data.astropy.org/
# Time to wait for remote data query (in seconds).
remote_timeout = 10.0
如果您希望修改 remote_timeout
值,但只针对代码的一小部分,那么 set_temp()
负责在使用完成后重置您更改的值::
>>> from astropy.utils.data import conf
>>> conf.remote_timeout
10.0
>>> # Change remote_timeout, but only inside the with-statement.
>>> with conf.set_temp('remote_timeout', 4.5):
... conf.remote_timeout
4.5
>>> conf.remote_timeout
10.0
您也可以在运行时直接修改这些值:
>>> conf.dataurl
'http://data.astropy.org/'
>>> conf.dataurl = 'http://astropydata.mywebsite.com'
>>> conf.dataurl
'http://astropydata.mywebsite.com'
>>> conf.remote_timeout
10.0
>>> conf.remote_timeout = 4.5
>>> conf.remote_timeout
4.5
重新加载配置#
您也可以修改配置文件,然后使用 reload()
方法。
例子#
如果将配置文件修改为:
[utils.data]
# URL for astropy remote data site.
dataurl = http://myotherdata.mywebsite.com/
# Time to wait for remote data query (in seconds).
remote_timeout = 6.3
然后运行以下命令:
>>> conf.reload('dataurl')
>>> conf.reload('remote_timeout')
这将使用配置文件中的值更新变量:
>>> conf.dataurl
'http://myotherdata.mywebsite.com/'
>>> conf.remote_timeout
6.3
您可以重新加载 conf
通过调用 reload()
不带参数::
>>> conf.reload()
或者,如果您想一次重新加载所有配置项,而不仅仅是模块中的配置项 conf
所属,请使用 reload_config()
功能::
>>> from astropy import config
>>> config.reload_config()
属性将配置参数重置回其默认值。 reset()
方法。请注意,这是在Python代码中定义的默认值,可能与配置文件中的值不同:
>>> conf.reset('dataurl')
>>> conf.dataurl
'http://data.astropy.org/'
正在探索配置#
查看为给定的 conf
::
>>> from astropy.utils.iers import conf
>>> list(conf)
['auto_download',
'auto_max_age',
...,
'ietf_leap_second_auto_url']
方法可以查看有关配置参数的更多详细信息 help()
方法:
>>> conf.help("auto_max_age")
ConfigItem: auto_max_age
cfgtype='float'
defaultvalue=30.0
description='Maximum age (days) of predictive data before auto-downloading. See "Auto refresh behavior" in astropy.utils.iers documentation for details. Default is 30.'
module=astropy.utils.iers.iers
value=30.0
您可以通过调用以下命令查看有关所有配置参数的信息 help()
不带参数::
>>> conf.help()
Configuration parameters for `astropy.utils.iers`.
ConfigItem: auto_download
cfgtype='boolean'
...
您也可以迭代 conf
像字典一样:
>>> for (key, cfgitem) in conf.items():
... print(f'{key} default value is {cfgitem.defaultvalue}')
auto_download default value is True
auto_max_age default value is 30.0
...
升级 astropy
#
每次升级到新的主要版本时 astropy
,配置参数可能已更改。如果要创建新的配置文件,可以运行:
>>> from astropy.config import create_config_file
>>> create_config_file('astropy', overwrite=True)
请注意,这将覆盖现有文件,因此如果您修改了它,您可能希望在新文件中报告您的更改。另一种可能是查看一下 配置系统 (astropy.config ) 看看发生了什么变化。
添加新配置项#
只要需要绑定到系统配置的选项或设置,或应在的会话中保持不变,就应使用配置项 astropy
或附属的套餐。可能影响科学计算结果的选项不应该是配置项,而应该是 ScienceState
实例,因此可以在不受特定环境中设置的配置参数影响的情况下重现科学结果。诚然,这只是一条指导方针,因为配置项比功能的关键字选项更受欢迎的确切情况在某种程度上是个人偏好。然而,它是持久配置的首选形式,并且 astropy
套餐必须全部使用它(推荐用于附属套餐)。
下面的参考指南描述了创建 conf
具有多个配置参数的对象。它们应该在顶层定义(即 __init__.py
包含配置项的每个子包)::
""" This is the docstring at the beginning of a module
"""
from astropy import config as _config
class Conf(_config.ConfigNamespace):
"""
Configuration parameters for my subpackage.
"""
some_setting = _config.ConfigItem(
1, 'Description of some_setting')
another_setting = _config.ConfigItem(
'string value', 'Description of another_setting')
some_list = _config.ConfigItem(
[], 'Description of some_list', cfgtype='list')
another_list = _config.ConfigItem(
['value'], 'Description of another_setting', cfgtype='list')
# Create an instance for the user
conf = Conf()
# implementation ...
def some_func():
# to get the value of some of these options, I might do:
something = conf.some_setting + 2
return conf.another_setting + ' Also, I added text.'
对于称为的附属包,例如, packagename
,则可以使用 create_config_file()
函数如下::
>>> from astropy.config import create_config_file
>>> create_config_file('packagename')
以下内容将写入配置文件模板:
[subpackage]
## Description of some_setting
# some_setting = 1
## Description of another_setting
# another_setting = foo
## Description of some_list
# some_list = ,
## Description of another_setting
# another_list = value,
请注意,键/值对被注释掉了。这将允许在程序包的未来版本中更改默认值,而无需用户编辑其配置文件以利用新的默认值。按照惯例,每个参数的描述都在以两个散列字符开头的注释行中 (##
)以将它们与注释掉的键/值对区分开来。
项目类型和验证#
如果未另行指定,则 ConfigItem
对象的类型获取其类型。 defaultvalue
它是在它被创建的时候给的。该项只能具有此类型的值,尽管在某些情况下可以自动转换提供的值。例如
>>> conf.auto_download
True
>>> conf.auto_download = 0
>>> conf.auto_download
False
成功是因为 int
0
可以安全地转换为 bool
False
。另一方面,
>>> from astropy.utils.data import conf
>>> conf.compute_hash_block_size
65536
>>> conf.compute_hash_block_size = 65536.0
Traceback (most recent call last):
...
TypeError: Provided value for configuration item compute_hash_block_size
not valid: the value "65536.0" is of the wrong type.
失败,因为将 float
发送到An int
可能会丢失信息。
请注意,如果希望将配置项限制为一组特定的选项,则应传入 list
作为 defaultvalue
选择。中的第一个条目 list
将被视为默认设置,并且 list
作为一个整体,给出了所有有效的选择。例如::
an_option = ConfigItem(['a', 'b', 'c'],
"This option can be 'a', 'b', or 'c'")
conf.an_option = 'b' # succeeds
conf.an_option = 'c' # succeeds
conf.an_option = 'd' # fails!
conf.an_option = 6 # fails!
最后,一个 ConfigItem
属性显式地赋予一个类型 cfgtype
选项::
an_int_setting = ConfigItem(
1, 'A description.', cfgtype='integer')
...
conf.an_int_setting = 3 # works fine
conf.an_int_setting = 4.2 # fails!
如果缺省值的类型不匹配 cfgtype
vt.的. ConfigItem
无法创建。
总而言之,默认行为(自动确定 cfgtype
)通常是您想要的。主要的例外是当您希望您的配置项是 list
。默认行为会将其视为 list of options 除非您明确地告诉它 ConfigItem
它本身应该是一种 list
**
# The setting must be 1, 2 or 3
a_list_setting = ConfigItem([1, 2, 3], 'A description.')
# The setting must be a list and is [1, 2, 3] by default
a_list_setting = ConfigItem([1, 2, 3], 'A description.', cfgtype='list')
所有有效的详细信息 cfgtype
这些项目可以在 validation section of the configobj manual 。以下是有效值列表,以供快速参考:
'integer'
'float'
'boolean'
'string'
'ip_addr'
'list'
'tuple'
'int_list'
'float_list'
'bool_list'
'string_list'
'ip_addr_list'
'mixed_list'
'option'
'pass'
使用提示#
请记住, ConfigItem
用户可以在运行时更改对象。因此,始终建议在使用之前立即读取它们的值,而不是将它们的初始值存储到其他变量(或用作函数的缺省值)。例如,以下用法不正确:
>>> from astropy.utils.data import conf
>>> conf.remote_timeout = 1.0
>>> def some_func(val=conf.remote_timeout):
... return val + 2
只有当用户在定义函数后不更改配置项的值时,此操作才有效,但如果用户更改,函数将不会知道更改:
>>> some_func()
3.0
>>> conf.remote_timeout = 3.0
>>> some_func() # naively should return 5.0, because 3 + 2 = 5
3.0
有两种方法可以解决这个问题。典型/预期的方式是:
>>> def some_func():
... """
... The `SOME_SETTING` configuration item influences this output
... """
... return conf.remote_timeout + 2
>>> some_func()
5.0
>>> conf.remote_timeout = 5.0
>>> some_func()
7.0
或者,如果选项需要作为函数参数使用:
def some_func(val=None):
"""
If not specified, `val` is set by the `SOME_SETTING` configuration item.
"""
return (conf.remote_timeout if val is None else val) + 2
自定义关联包中的配置位置#
这个 astropy.config
包可以被其他包使用。默认情况下,在另一个包中创建配置对象将导致配置文件使用 astropy
配置目录(即。, <astropy_config>/packagename.cfg
)
可以配置此行为,以便为包创建自定义配置目录,例如, ~/.packagename/packagename.cfg
. 为此,创建一个 packagename.config
分装并将以下内容放入 __init__.py
文件::
import astropy.config as astropyconfig
class ConfigNamespace(astropyconfig.ConfigNamespace):
rootname = 'packagename'
class ConfigItem(astropyconfig.ConfigItem):
rootname = 'packagename'
然后替换所有导入的 astropy.config
具有 packagename.config
.
也见#
日志系统 (概述 astropy.logger
)