何时使用静态和 class 方法
When to use static and class methods
我知道有很多关于这个主题的话题,我也看过很多。但是,当使用静态方法和 class 方法代替实例方法时,我仍然感到困惑。
在我的示例中,我正在为 Autodesk 程序 Maya 制作脚本。我的一个模块中有一个 class,其中包含将在其中生成对象的方法,如下所示:
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 或模块外部访问该方法,它是否需要是一个实例?在这种情况下,静态或 class 方法是否合适,因为在这种情况下我不需要单独的实例,它只做一件事,从不改变大小或形状,稍后会调整大小。
接下来,如果我在 class 中有一个方法只执行如下所示的简单计算,静态方法是否合适?因为它每次只是接受输入和输出一个东西,有什么理由让它成为一个实例吗?:
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
最后,我知道很多人说在这些情况下,这些根本不应该在 class 中,或者类似的东西,但这就是我想要的方式,我只是想要更深入地了解何时使用这些类型的方法。
简单来说,一个实例就是一个实体,一个class就是实体的概念。比如你有一个class Human,那么instance就是人,而Humanclass对应的是人的概念。例如,衡量一个人产生的污染程度是没有意义的。衡量人类造成的污染更有意义。因此,如果您有一个名为 measureGeneratedPollution 的方法,它应该是静态的。但是,如果你有一个名为 breath 的方法,那么很自然这是一个单独的动作,所以 breath 应该是一个实例级方法。实例级与静态级本质上类似于个人行动与集体行动。
让我们再看一个成员的例子。让我们考虑 class 鸟。鸟,集体没有颜色,所以颜色应该是实例级成员。但是birdCount是一个集合信息,应该是静态的。
请记住,对于 members/methods,级别(实例或 class 级别)不是由可访问性决定的,而是由具有属性或执行操作的主体决定的。所以,如果我们把它翻译成句子逻辑,那么你应该在制定这样的计划时给自己写下句子,直到你变得更专业。句子,例如:
The bird has a color.
There is a number of birds.
问自己问题:
Who has a color? -> the bird -> singular -> instance Who have the
number? -> the birds -> plural -> collective -> static
我知道有很多关于这个主题的话题,我也看过很多。但是,当使用静态方法和 class 方法代替实例方法时,我仍然感到困惑。
在我的示例中,我正在为 Autodesk 程序 Maya 制作脚本。我的一个模块中有一个 class,其中包含将在其中生成对象的方法,如下所示:
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 或模块外部访问该方法,它是否需要是一个实例?在这种情况下,静态或 class 方法是否合适,因为在这种情况下我不需要单独的实例,它只做一件事,从不改变大小或形状,稍后会调整大小。
接下来,如果我在 class 中有一个方法只执行如下所示的简单计算,静态方法是否合适?因为它每次只是接受输入和输出一个东西,有什么理由让它成为一个实例吗?:
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
最后,我知道很多人说在这些情况下,这些根本不应该在 class 中,或者类似的东西,但这就是我想要的方式,我只是想要更深入地了解何时使用这些类型的方法。
简单来说,一个实例就是一个实体,一个class就是实体的概念。比如你有一个class Human,那么instance就是人,而Humanclass对应的是人的概念。例如,衡量一个人产生的污染程度是没有意义的。衡量人类造成的污染更有意义。因此,如果您有一个名为 measureGeneratedPollution 的方法,它应该是静态的。但是,如果你有一个名为 breath 的方法,那么很自然这是一个单独的动作,所以 breath 应该是一个实例级方法。实例级与静态级本质上类似于个人行动与集体行动。
让我们再看一个成员的例子。让我们考虑 class 鸟。鸟,集体没有颜色,所以颜色应该是实例级成员。但是birdCount是一个集合信息,应该是静态的。
请记住,对于 members/methods,级别(实例或 class 级别)不是由可访问性决定的,而是由具有属性或执行操作的主体决定的。所以,如果我们把它翻译成句子逻辑,那么你应该在制定这样的计划时给自己写下句子,直到你变得更专业。句子,例如:
The bird has a color.
There is a number of birds.
问自己问题:
Who has a color? -> the bird -> singular -> instance Who have the
number? -> the birds -> plural -> collective -> static