Я пытаюсь заставить класс выдать число с единицами. Целью наличия единиц была бы возможность работать с числом позже, но без единиц, мешающих в виде строки. Хотя я понятия не имею, как это сделать. Я новичок в (на самом деле понимающих) классах, я даже не уверен, возможно ли то, что я прошу, или нет.
Моя цель — создать класс для создания атомов на основе их протонов, электронов и нейтонов. То, что я хочу попробовать, - это иметь возможность видеть единицы массы (в килограммах для моей цели), когда я пытаюсь ее распечатать. Вот что у меня есть:
class Atom:
def __init__(self, protons, electrons, neutrons):
ElemCharge = 1.6021765*(10**-19)
UMAS = 1.66054*(10**-27)
self.protons = protons
self.electrons = electrons
self.neutrons = neutrons
self.charge = ElemCharge*(self.protons - self.electrons)
self.mass = (self.protons + self.neutrons)*UMAS
def main():
Hydrogen = Atom(1,1,0)
print (Hydrogen.mass)
Argon = Atom(18,18,22)
print (Argon.mass)
if __name__ == "__main__":
main()
Этот код работает совершенно нормально, так что не беспокойтесь об этом: p
Есть ли способ сделать это? Если да, то как это можно сделать? Спасибо!






Я не уверен, что это именно то, что вы ищете, но у вас может быть метод внутри класса Atom, который печатает массу атома плюс строку единиц.
class Atom:
def __init__(self, protons, electrons, neutrons):
ElemCharge = 1.6021765*(10**-19)
UMAS = 1.66054*(10**-27)
self.protons = protons
self.electrons = electrons
self.neutrons = neutrons
self.charge = ElemCharge*(self.protons - self.electrons)
self.mass = (self.protons + self.neutrons)*UMAS
def print_mass_str(self):
print('{} {}'.format(self.mass, 'kg'))
Тогда это:
Argon = Atom(18,18,22)
print(Argon.mass)
Argon.print_mass_str()
будет печатать:
6.64216e-26
6.64216e-26 kg
Спасибо :p К сожалению, это то, чего я пытаюсь избежать, чтобы иметь возможность затем использовать тот же «6.64216e-26 кг» и не иметь никаких ошибок, поскольку он является str и не теряет единицы измерения. Но это сработает иначе :)
Это работает?
По сути, я добавил еще один property к классу Atom, чтобы все объекты типа Atom могли его использовать. Другой способ сделать это - передать его, как вы делаете с нейтронами/протонами/электронами. Таким образом, вы можете выполнять свои собственные расчеты (если это необходимо) с учетом единицы (скажем, вы хотите показать вес в граммах для водорода, а в килограммах для аргона)
class Atom:
def __init__(self, protons, electrons, neutrons):
ElemCharge = 1.6021765*(10**-19)
UMAS = 1.66054*(10**-27)
self.protons = protons
self.electrons = electrons
self.neutrons = neutrons
self.charge = ElemCharge*(self.protons - self.electrons)
self.mass = (self.protons + self.neutrons)*UMAS
self.massUnit = "kgs"
def main():
Hydrogen = Atom(1,1,0)
print ("{0} {1}".format(Hydrogen.mass,Hydrogen.massUnit))
Argon = Atom(18,18,22)
print ("{0} {1}".format(Argon.mass,Argon.massUnit))
if __name__ == "__main__":
main()
Выход
1.66054e-27 kgs
6.64216e-26 kgs
Есть ли способ предотвратить необходимость ввода дополнительного шага форматирования числа?
Да, вы можете переопределить методы ул или репр.
Чтобы переопределить строковое представление числа, создайте класс-оболочку:
class FloatWrapper:
def __init__(self, float, unit):
self.float = float
self.unit = unit
def __getattr__(self, key):
try:
return object.__getattr__(self, key)
except AttributeError:
return getattr(self.float, key)
def __str__(self):
return str(self.float) + self.unit
Теперь в вашем __init__, после определения self.mass, добавьте:
self.mass = FloatWrapper(self.mass, 'kg')
Я пошел дальше и протестировал это, но, к сожалению, результат был не таким, как я ожидал :( Когда я пытаюсь: распечатать (Argon.mass*3), появляется только ошибка, которая говорит: «Ошибка типа: неподдерживаемые типы операндов для *: 'FloatWrapper' и 'int'"
Есть способы сделать это, но сначала вы должны спросить себя, хотите ли вы этого. Наличие разных единиц может привести к путанице. Вы можете поместить преобразования в соответствующие места (например, после чтения ввода от пользователя) и заставить вашу систему работать исключительно с заданной единицей (в конце концов, поэтому у нас есть единицы СИ). Возможность внутренней поддержки нескольких модулей не только усложняет код, но и создает еще один источник возможной путаницы.
Есть пакеты, которые делают это за вас, например units, numericalunits или pint.
Пример, взятый из документации units:
>>> from units import unit
>>> metre = unit('m')
>>> second = unit('s')
>>> print(metre(10) / second(2))
5.00 m / s
>>> print(metre(10) ** 3)
1000.00 m * m * m
Посмотрите, как metre создает значение счетчика и отслеживает его использование. Он также поддерживает определение пользовательских единиц измерения.
Поэтому вы можете просто сохранить значения в своем классе как значения из units или другого пакета, и все готово. Я немного изучил код из units, и он довольно короткий, и я думаю, что это хороший источник информации о том, как обрабатывать подобные вещи в вашем собственном коде.
Я должен процитировать отказ марсианского климатического орбитального аппарата НАСА, который был вызван расхождением в единицах измерения.
Это просто идеально! Спасибо
Определите метод
__str__, который возвращает строку, когда к ней вызываетсяstr()(во время печати). Если вы хотите, чтобы фактическое значение массы имело единицу измерения, вам нужно определить класс-оболочку для хранения числа, но переопределить его__str__