Mik*_*lla 69 python oop neuroscience
我正在使用神经元模型.我正在设计的一个类是一个细胞类,它是神经元的拓扑描述(几个连接在一起的隔室).它有许多参数,但它们都是相关的,例如:
轴突节段数,顶端双分裂,体长,体细胞直径,顶端长度,分枝随机性,分枝长度等等...总共约有15个参数!
我可以将所有这些设置为某个默认值,但我的课看起来很疯狂,有几行参数.这种事情也偶尔会发生在其他人身上,是否有一些明显更好的方法来设计这个或者我做对了吗?
更新: 正如你们中的一些人已经要求我已经为类添加了我的代码,因为你可以看到这个类有大量的参数(> 15)但它们都被使用并且是定义单元格拓扑所必需的.问题主要在于他们创建的物理对象非常复杂.我附上了这个类产生的对象的图像表示.有经验的程序员如何以不同的方式做到这一点以避免定义中的这么多参数?
class LayerV(__Cell):
def __init__(self,somatic_dendrites=10,oblique_dendrites=10,
somatic_bifibs=3,apical_bifibs=10,oblique_bifibs=3,
L_sigma=0.0,apical_branch_prob=1.0,
somatic_branch_prob=1.0,oblique_branch_prob=1.0,
soma_L=30,soma_d=25,axon_segs=5,myelin_L=100,
apical_sec1_L=200,oblique_sec1_L=40,somadend_sec1_L=60,
ldecf=0.98):
import random
import math
#make main the regions:
axon=Axon(n_axon_seg=axon_segs)
soma=Soma(diam=soma_d,length=soma_L)
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)
#make the somatic denrites
somatic_dends=self.dendrite_list(num_dends=somatic_dendrites,
bifibs=somatic_bifibs,first_sec_L=somadend_sec1_L,
first_sec_d=1.5,L_sigma=L_sigma,
branch_prob=somatic_branch_prob,L_decrease_factor=ldecf)
#make oblique dendrites:
oblique_dends=self.dendrite_list(num_dends=oblique_dendrites,
bifibs=oblique_bifibs,first_sec_L=oblique_sec1_L,
first_sec_d=1.5,L_sigma=L_sigma,
branch_prob=oblique_branch_prob,L_decrease_factor=ldecf)
#connect axon to soma:
axon_section=axon.get_connecting_section()
self.soma_body=soma.body
soma.connect(axon_section,region_end=1)
#connect apical dendrite to soma:
apical_dendrite_firstsec=main_apical_dendrite.get_connecting_section()
soma.connect(apical_dendrite_firstsec,region_end=0)
#connect oblique dendrites to apical first section:
for dendrite in oblique_dends:
apical_location=math.exp(-5*random.random()) #for now connecting randomly but need to do this on some linspace
apsec=dendrite.get_connecting_section()
apsec.connect(apical_dendrite_firstsec,apical_location,0)
#connect dendrites to soma:
for dend in somatic_dends:
dendsec=dend.get_connecting_section()
soma.connect(dendsec,region_end=random.random()) #for now connecting randomly but need to do this on some linspace
#assign public sections
self.axon_iseg=axon.iseg
self.axon_hill=axon.hill
self.axon_nodes=axon.nodes
self.axon_myelin=axon.myelin
self.axon_sections=[axon.hill]+[axon.iseg]+axon.nodes+axon.myelin
self.soma_sections=[soma.body]
self.apical_dendrites=main_apical_dendrite.all_sections+self.seclist(oblique_dends)
self.somatic_dendrites=self.seclist(somatic_dends)
self.dendrites=self.apical_dendrites+self.somatic_dendrites
self.all_sections=self.axon_sections+[self.soma_sections]+self.dendrites
Run Code Online (Sandbox Code Playgroud)
blu*_*ubb 66
试试这种方法:
class Neuron(object):
def __init__(self, **kwargs):
prop_defaults = {
"num_axon_segments": 0,
"apical_bifibrications": "fancy default",
...
}
for (prop, default) in prop_defaults.iteritems():
setattr(self, prop, kwargs.get(prop, default))
Run Code Online (Sandbox Code Playgroud)
然后你可以创建一个Neuron
这样的:
n = Neuron(apical_bifibrications="special value")
Run Code Online (Sandbox Code Playgroud)
oni*_*ake 16
我认为这种方法没有任何问题 - 如果你需要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])
Run Code Online (Sandbox Code Playgroud)
看起来你可以通过构建物体,如减少参数的个数Axon
,Soma
和DendriticTree
外面的LayerV构造,并通过这些对象来代替.
一些参数仅用于构建,例如DendriticTree
,其他参数也用于其他地方,所以问题不是那么明确,但我肯定会尝试这种方法.