2017-01-07 7 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 для доступа Значение.

Это в основном класс, который ведет себя как класс float , но содержит две дополнительные строки: единицы измерения и документацию. Как это можно спроектировать?

+0

Я довольно конечно, это невозможно - cR подразумевает, что он плавает на самом следующем вызове, который вам не нужен, чтобы получить доступ к атрибуту e of float, который является простым типом ... Вместо этого вы должны использовать cR() или cRval, что позволило бы это сделать – MacHala

+1

Вы должны посмотреть на [этот scipy module] (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

Есть опечатка: 'units' должно быть' unit' или наоборот. – cdonts

+0

Наследование 'float' является супер-пуперным, подверженным ошибкам. В этом случае лучше использовать композицию. –

+0

@MikeGraham: для констант это нормально, потому что никто не ожидает, что производные числа ведут себя как новый класс, но как 'float's. – Daniel

1

Я рекомендую использовать библиотеку json, которая позволит вам сохранять ваши постоянные значения в читаемом и изменяемом формате.

Используя класс @ Daniel Constant, который наследует от 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" 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^