我知道关于这个主题有很多话题,我看了很多。然而,当何时适当使用静态和类方法代替实例方法仍然令我感到困惑。
在我的例子中,我正在为autodesk程序maya制作一个脚本。其中一个模块有一个包含生成对象的方法的类,如下所示:
class Curves(object):
"""Contains methods to generate curves
"""
@classmethod
def circle_crv(cls):
name = mc.circle( nr=(0, 1, 0), c=(0, 0, 0), r=0.5 )
mc.delete(name, ch=True)
mc.addAttr(name[0], ln='crvType', dt='string', h=True)
mc.setAttr(name[0]+'.crvType', 'circle_crv', typ='string', l=True)
return name[0]
然而,这些方法永远不会被外部模块直接访问。我通过一个字典运行所有这些方法,该字典由外部模块访问(首先搜索外部用户字典),如下所示:
def curve_lib(self, crvtype):
"""Creates a specified curve at origin
Args:
crvtype (str): a key to call a function to generate a curve at the
origin
"""
userlib = self.usercurve_lib()
curves_dic = {
'bendjoint_crv' : self.bendjoint_crv,
'circle_crv' : self.circle_crv,
'circlearrow_crv' : self.circlearrow_crv,
'connectjoint_crv' : self.connectjoint_crv,
'fktext_crv' : self.fktext_crv,
'joint_crv' : self.joint_crv,
'iktext_crv' : self.iktext_crv,
'cube_crv' : self.cube_crv,
'quadarrow01_crv' : self.quadarrow01_crv,
'quadarrow02_crv' : self.quadarrow02_crv,
'quadarrow03_crv' : self.quadarrow03_crv,
'quadarrow04_crv' : self.quadarrow04_crv,
'rootjoint_crv' : self.rootjoint_crv,
'square_crv' : self.square_crv,
'switch_crv' : self.switch_crv,
'triangle_crv' : self.triangle_crv
}
if crvtype in userlib:
name = self.usercurve_lib(crvtype)
elif crvtype in curves_dic:
name = curves_dic[crvtype]()
else:
raise NameError('Key "%s" not found' %(crvtype))
return name
首先的问题是,如果该方法从未从类或模块之外访问过,那么它需要成为一个实例吗?在这种情况下,静态方法或类方法是否合适,因为我不需要此方法的单独实例,它只完成一件事情,并且永远不会更改大小或形状,稍后进行调整。
其次,如果我在类中有一个执行简单计算的方法,例如下面所示,那么静态方法是否适合?由于它只是接受输入并每次输出一个单个值,是否有任何理由使其成为实例?
class Vectors(object):
"""Contains methods for various vector math functions
"""
@staticmethod
def pointLineDist(vec_a, vec_b, vec_c):
"""The distance between the line ab and the point c.
Args:
vec_a (float list): First vector to find distance of.
vec_b (float list): Second vector to find distance of.
vec_c (float list): Third vector to find distance of.
"""
ab = dt.Vector(vec_b) - dt.Vector(vec_a)
ac = dt.Vector(vec_c) - dt.Vector(vec_a)
length = dt.length(dt.cross(ab, ac)) / dt.length(ab)
return length
最后,我知道很多人在这种情况下会说,这些东西根本不应该出现在课堂上,或者类似的话,但这是我想要的方式,我只是想更深入地了解何时使用这些类型的方法。