2017-01-07 30 views
3

我想爲我的物理常量設置一個地方。如何在python中保存常用的物理常數

以下的答案已經是一個起點: How-to import constants in many files

所以我叫constants.py我導入到我的項目中一個單獨的文件。現在

,我想保存和訪問更多的信息:

  • 單位
  • 文檔

生成的接口應該是這樣的:

import constants as c 

print c.R 
>>> 287.102 
print c.R.units 
>>> J/(kg K) 
print c.R.doc 
>>> ideal gas constant 

計算應使用cR訪問 價值。

它基本上是一個類,其行爲類似於浮點類 ,但包含兩個附加字符串:單位和文檔。 這是如何設計的?

+0

我敢肯定這是不可能的 - cR意味着它在你想訪問attribut的下一次調用中浮動浮點數,這是簡單的類型...你應該考慮使用cR()或cRval,這將使它成爲可能 – MacHala

+1

你應該看看[這個scipy模塊](https://docs.scipy.org/doc/ scipy/reference/constants.html) – Lucas

+0

可以使用子類或使用委託並實現所有特殊方法。哪個選擇最好取決於(雖然我會傾向於代表團以最少的驚喜)。 – Bakuriu

回答

4

float類繼承,你必須覆蓋__new__ - 方法:

class Constant(float): 
    def __new__(cls, value, units, doc): 
     self = float.__new__(cls, value) 
     self.units = units 
     self.doc = doc 
     return self 

R = Constant(287.102, "J/(kg K)", "deal gas constant") 

print R, R * 2 
>>> 287.102 574.204 
print R.units 
>>> J/(kg K) 
print R.doc 
>>> ideal gas constant 
+0

有一個錯字:「單位」應該是「單位」,反之亦然。 – cdonts

+0

繼承'float'是超級容易出錯的。在這種情況下使用組合更好。 –

+0

@MikeGraham:對於常量來說,沒關係,因爲沒有人會期望,派生數字的行爲就像新類一樣,但像'浮動'一樣。 – Daniel

1

我推薦使用json庫,它允許你以可讀和可修改的格式存儲你的常量值。

使用@ Daniel's常量類繼承自float並添加您的自定義屬性,您可以一次將所有常量加載到新的Constants對象中。

然後,您可以獲取這些屬性作爲c.R來訪問該值。

完整的文件:

#!/usr/bin/env python 
import json 

class Constant(float): 
    def __new__(cls, value): 
     self = float.__new__(cls, value["value"]) # KeyError if missing "value" 
     self.units = value.get("units", None) 
     self.doc = value.get("doc", None) 
     return self 

class Constants(): 
    # load the json file into a dictionary of Constant objects 
    def __init__(self): 
     with open("constants.json") as fh: 
      json_object = json.load(fh) 

     # create a new dictionary 
     self.constants_dict = {} 
     for constant in json_object.keys(): 
      # put each Constant into it 
      self.constants_dict[constant] = Constant(json_object[constant]) 

    # try to get the requested attribute 
    def __getattr__(self, name): 
     # missing keys are returned None, use self.constants_dict[name] 
     # if you want to raise a KeyError instead 
     return self.constants_dict.get(name, None) 

c = Constants() 
print c.R   # 287.102 
print c.R.doc  # ideal gas constant 
print c.R + 5  # 292.102 
print c.F.units # C mol-1 
print c.missing # None 

例constants.json:

{ 
    "R": { 
     "value": 287.102, 
     "units": "J/(kg K)", 
     "doc": "ideal gas constant" 
    }, 
    "F": { 
     "value": 96485.33, 
     "units": "C mol-1", 
     "doc": "Faraday contant" 
    } 
}