#python #oop
#python #ооп
Вопрос:
Допустим, у меня есть 2 класса: Water
и Substance
. один или несколько Substance
s могут быть растворены в Water
; у Water
экземпляра есть substances
атрибут, содержащий список Substance
экземпляров. Константа диффузии a Substance
зависит от атрибутов Water
, в которых он растворен, а также от некоторых атрибутов Substance
самого. Должен ли я затем создать get_diffusion_constant
метод на Water
с экземпляром Substance
в качестве атрибута, или я должен добавить метод в, Substance
где Water
его аргумент? Или есть совсем другой подход?
Комментарии:
1. Вы написали «Константа диффузии вещества», что означает, что константа диффузии является атрибутом вещества. Таким образом,
get_diffusion_constant
должен быть методSubstance
2. да, это допустимый аргумент. Я подумал то же самое. Но теперь, когда у меня есть другой метод,
Water
который вычисляет некоторое свойство вещества, зависящее от константы диффузии, я пишу:self.substances[0].get_diffusion_constant(self)
. Особенно self в качестве аргумента кажется мне странным3. Использование
self
в качестве аргумента меня не беспокоит. Это просто ссылка наWater
экземпляр, как и на любой другойWater
экземпляр.self
Имя аргумента — это просто соглашение, которое, к счастью, используется всеми. Но технически в нем нет ничего особенного; вы могли бы определить свои методы с помощьюthis
(илиfoo
, или чего-либо еще) в качестве первого параметра и использоватьthis
(илиfoo
, или что-нибудь еще) в качестве текущего экземпляра, это также сработало бы.4. Я не уверен, как это вписывается в общий дизайн вашей системы, но другим вариантом является класс DiffusionConstant, который использует воду (и вещества?) в качестве аргументов конструктора. Он может либо выполнять вычисление как часть конструктора, либо как метод (возможно, с именем value).
5. @Tryph да, спасибо за заверение, что это нормальное кодирование. Я оставлю это таким образом. Вы могли бы сделать из этого ответ, и я приму его.
Ответ №1:
Вы написали:
Константа распространения
Substance
зависит от атрибутовWater
Это позволяет думать, что константа диффузии является характеристикой вещества, поэтому Substance
классу должен принадлежать метод, позволяющий его вычислять (с параметром для предоставления Water
экземпляра, поскольку это зависит от него).
Это хорошо работает для самого простого случая, если real concepts владеет характеристикой, его модели (в данном случае классу) должен принадлежать соответствующий атрибут или метод.
Некоторые шаблоны проектирования и / или более сложные потребности могут оправдать нарушение этого «правила» для введения большего ограничения.
Кроме того, чтобы ответить на ваш комментарий: передача self
функции не является проблемой (по крайней мере, IMO). self
это просто ссылка на текущий экземпляр и ничего особенного, за исключением того, что это широко уважаемое соглашение об именовании текущего экземпляра и, следовательно, первого аргумента методов (экземпляра).
Чтобы объяснить немного больше: метод экземпляра должен принимать в качестве первого аргумента ссылку на связанный экземпляр. По соглашению, этот позиционный аргумент называется self
, но вы могли бы назвать его this
, instance
или как угодно, это было бы то же самое. Тогда вам просто нужно будет использовать правильное имя параметра внутри метода.
Смотрите код ниже. Он использует очень плохие имена для аргумента экземпляра, но он работает так, как если бы self
использовался:
class Foo:
def __init__(current_instance):
current_instance.bar = 'baz'
def __str__(this_name_is_ridiculous):
return this_name_is_ridiculous.bar
print(Foo()) # prints baz
Ответ №2:
Я предполагаю, что это Water
наследует некоторые вещи от Substance
. Таким образом, у вас может быть diffusion_constant
в каждом Substance
, а также diffuse
функция, которая принимает один или несколько Substance
с
Редактировать:
class Water:
def diffuse(self, *args):
#check if args is greater 0 or None and then iterate and apply diffusion_constants
class Substance:
diffusion_constant = 0 #base constant
class Sirup(Substance):
diffusion_constant = 3
#somewhere later then
corn_sirup = Sirup()
sugary_sirup = Sirup()
water = Water()
water.diffuse(corn_sirup, sugary_sirup)
Редактировать:
Из-за комментария я изменил код. В Python есть утиный ввод, поэтому, пока ваши вещества имеют diffusion_constant
атрибут, к нему можно получить доступ, независимо от того, что это такое. Тогда это должно сработать
Комментарии:
1. Извините, вода не наследуется от вещества. Я вижу путаницу, поскольку вода в некотором смысле является веществом. Но вещества в моем случае относятся к веществам, растворенным в воде