Да, PHP_EOL
якобы используется для нахождения символа новой строки кросс-платформенно-совместимым способом, таким образом, он обрабатывает проблемы DOS/Unix.
Примечание, что PHP_EOL представляет endline символ для текущий система. Например, это не найдет Windows endline, когда выполняется в подобной Unix системе.
Я бы сказал, что в этом подходе нет ничего плохого - если вам нужно 15 параметров для моделирования чего-либо, вам нужно 15 параметров. И если нет подходящего значения по умолчанию, вы должны передать все 15 параметров при создании объекта. В противном случае вы можете просто установить значение по умолчанию и изменить его позже с помощью установщика или напрямую.
Другой подход заключается в создании подклассов для некоторых распространенных типов нейронов (в вашем примере) и обеспечении хороших значений по умолчанию для определенных значений или получения значений из других параметров.
Или вы можете заключить части нейрона в отдельные классы и повторно использовать эти части для реальных нейронов, которые вы моделируете. То есть вы могли бы написать отдельные классы для моделирования синапса, аксона, сомы и т. Д.
Наличие стольких параметров говорит о том, что класс, вероятно, делает слишком много вещей.
Я предлагаю вам разделить ваш класс на несколько классов, каждый из которых принимает некоторые из ваших параметров. Таким образом, каждый класс проще и не будет принимать столько параметров.
Не зная больше о вашем коде, я не могу точно сказать, как вы должны его разделить.
Не могли бы вы привести пример кода того, над чем вы работаете? Это помогло бы получить представление о том, что вы делаете, и получить помощь раньше.
Если только аргументы, которые вы передаете классу, делают его длинным, вам не нужно помещать все это в __init__
. Вы можете установить параметры после создания класса или передать словарь / класс, полный параметров, в качестве аргумента.
class MyClass(object):
def __init__(self, **kwargs):
arg1 = None
arg2 = None
arg3 = None
for (key, value) in kwargs.iteritems():
if hasattr(self, key):
setattr(self, key, value)
if __name__ == "__main__":
a_class = MyClass()
a_class.arg1 = "A string"
a_class.arg2 = 105
a_class.arg3 = ["List", 100, 50.4]
b_class = MyClass(arg1 = "Astring", arg2 = 105, arg3 = ["List", 100, 50.4])
Мне никогда не приходилось сталкиваться с этой ситуацией или этой темой. Ваше описание подразумевает для меня, что при разработке дизайна вы можете обнаружить, что есть ряд дополнительных классов, которые станут актуальными - купе является наиболее очевидным. Если они появляются как классы сами по себе, вполне вероятно, что некоторые из ваших параметров станут параметрами этих дополнительных классов.
Это похоже на другие решения, которые перебирают словарь по умолчанию, но использует более компактную запись:
class MyClass(object):
def __init__(self, **kwargs):
self.__dict__.update(dict(
arg1=123,
arg2=345,
arg3=678,
), **kwargs)
На мой взгляд, в вашем случае самое простое решение - передать объекты более высокого порядка в качестве параметра.
Например, в вашем __init__
у вас есть DendriticTree
, который использует несколько аргументов из вашего основного класса LayerV
:
main_apical_dendrite = DendriticTree(
bifibs=apical_bifibs,
first_sec_L=apical_sec1_L,
L_sigma=L_sigma,
L_decrease_factor=ldecf,
first_sec_d=9,
branch_prob=apical_branch_prob
)
Вместо передачи этих 6 аргументов вашему LayerV
вы бы передавали объект DendriticTree
напрямую (сохраняя 5 аргументов).
Возможно, вы хотите, чтобы эти значения были доступны везде, поэтому вам придется сохранить это DendriticTree
:
class LayerV(__Cell):
def __init__(self, main_apical_dendrite, ...):
self.main_apical_dendrite = main_apical_dendrite
Если вы хотите иметь значение по умолчанию, вы можете иметь:
class LayerV(__Cell):
def __init__(self, main_apical_dendrite=None, ...):
self.main_apical_dendrite = main_apical_dendrite or DendriticTree()
Таким образом, вы делегируете то, что должно быть по умолчанию DendriticTree
, классу, посвященному этому вопросу, вместо того, чтобы иметь эту логику в классе более высокого порядка, чем LayerV
.
Наконец, когда вам нужно получить доступ к apical_bifibs
, который вы использовали для перехода к LayerV
, вы просто получаете к нему доступ через self.main_apical_dendrite.bifibs
.
В общем, даже если создаваемый вами класс не является четкой композицией из нескольких классов, ваша цель - найти логический способ разделения ваших параметров. Не только для того, чтобы сделать ваш код чище, но и для того, чтобы помочь людям понять, для чего эти параметры будут использоваться. В крайних случаях, когда вы не можете их разделить, я думаю, что вполне нормально иметь класс с таким количеством параметров. Если нет четкого способа разделения аргументов, вы, вероятно, в конечном итоге получите что-то еще менее ясное, чем список из 15 аргументов.
Если вы чувствуете, что создание класса для группировки параметров является излишним, то вы можете просто использовать collections.namedtuple
, который может иметь значения по умолчанию, как , показанное здесь . [1 125]