模块上的属性?

时间:2016-08-16 03:26:32

标签: python properties module

这可能看起来像是重复的;这是场景:

default_config.py:

unit_id = -1  # a serial number; int. -1 is a test unit, for example

def um():
    return unit_id % 60  # stagger uploads

upload_hour = 2  #am
upload_minute = property( um )  # <- something that works needed here...

config.py

from default_config import *
# Override defaults here, if necessary

unit_id = 12  # ACTUAL serial number...

some_file.py

import config as cfg

do_something(cfg.upload_hour, cfg.upload_minute)

print cfg.upload_minute * 5  # should be an int...?

所以,目标是:

  • 特定的配置文件可以覆盖默认值,工作正常
  • 在应用覆盖后,可以访问计算的某些值 - 但是采用“透​​明”方式(即没有prop()括号)

对于python属性来说这似乎很简单,但是在各种组合之后,它们都不起作用。我猜它与在模块上定义的函数有关,而不是对象,以及未绑定的第一个变量等......

要么我得到一个“属性对象”,然后就不能在它上面使用运算符等,或者我无法得到属性应该计算和返回的值,或者在多次迭代之后我都记不清了,其他一些错误...

2 个答案:

答案 0 :(得分:0)

  

我猜它与在a上定义的函数有关   模块,而不是对象...

为什么不使用对象呢? :)

<强> default_config.py

<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>

<body ng-app="KnobDemoApp">
  <div ng-controller="knobCtrl as knob">
    <label>Yes/No:</label>
    <select ng-model="knob.yesno"
            name="yesnoName"
            ng-options="x for x in yes_no"
            ng-change="setValue()">
      <option value hidden>Select One</option>
    </select>
    <br>
    <label>Number:</label>
    <input type="number"
           ng-model="numyesno"
           name="numName"
           ng-disabled="knob.yesno !== 'Yes'"
           min="{{knob.yesno === 'Yes' ? 1 : ''}}">
    <br>
    <br>
    <span> Value: </span>{{knob.yesno}}
    <br>
    <span> Check: </span>{{knob.yesno != 'Yes'}}
  </div>
</body>

</html>

<强> config.py

_DEFAULT_UNIT_ID = -1
_DEFAULT_UPLOAD_HOUR = 2
_MINUTES_PER_HOUR = 60


class BaseConfig(object):
    def __init__(self, unit_id=_DEFAULT_UNIT_ID, upload_hour=_DEFAULT_UPLOAD_HOUR):
        self.unit_id = unit_id
        self.upload_hour = upload_hour

    @property
    def upload_minute(self):
        return self.unit_id % _MINUTES_PER_HOUR

<强> some_file.py

from default_config import BaseConfig

# organized place to put non-default parameters
config_dict = {
    'unit_id': 12,
    'upload_hour': 3,
}

CONFIG = BaseConfig(**config_dict)

如果不需要将它们分开,我还会考虑将default_config.py和config.py组合起来,因为更容易看到from config import CONFIG print CONFIG.upload_hour, CONFIG.upload_minute # "3 12" 所采用的关键字参数。

答案 1 :(得分:0)

您无法在模块上定义特殊方法,但sys.modules中的条目不必是模块对象,它们也可以是类实例对象。这意味着您可以利用其属性访问特殊方法,如下所示:

<强> default_config.py

class DefaultConfig(object):
    unit_id = -1  # a serial number
    upload_hour = 2  # am

    @property
    def upload_minute(self):
        return self.unit_id % 60  # stagger uploads

<强> config.py

import sys
from default_config import DefaultConfig

# override defaults
DefaultConfig.unit_id = 12

# see http://stackoverflow.com/questions/5365562/why-is-the-value-of-name-changing-after-assignment-to-sys-modules-name
# as to why the _ref is necessary
_ref, sys.modules[__name__] = sys.modules[__name__], DefaultConfig()

# clean up this module's namespace
del sys, DefaultConfig

<强> some_file.py

from __future__ import print_function
import config as cfg

def do_something(hour, minute):
    print('do_something({}, {}) called'.format(hour, minute))

do_something(cfg.upload_hour, cfg.upload_minute)
print(cfg.upload_minute * 5)

运行some_file.py的输出:

do_something(2, 12) called
60