我有以下嵌套类:
class Classifiers(object):
class RF():
@staticmethod
def classifier():
print "RF CLASF"
return
class KN():
def create_model(self):
print "This is KN Model"
return
@staticmethod
def classifier():
arg = self.create_model()
第一课RF
我可以使用以下方式成功执行:
rf = Classifiers.RF()
rf_clsf = rf.classifier()
# prints RF CLASF
但是当我以下列方式调用第二个班级KN
时:
kn = Classifiers.KN()
kn_clsf = kn.classifier()
我收到了一个错误:
Traceback (most recent call last)
NameError
<ipython-input-32-5d9ba3c7c927> in <module>()
----> 1 kn_clsf = kn.classifier()
<ipython-input-28-6147200d928b> in classifier()
15 @staticmethod
16 def classifier():
---> 17 arg = self.create_model()
NameError: global name 'self' is not defined
我期望它打印&#34;这是KN模型&#34;。 什么是正确的方法?
答案 0 :(得分:2)
你使这个方法成为一个静态函数;这将从函数中删除所有上下文(它仍然未绑定)。
您可以将方法改为 classmethod
,因此它绑定到类:
class KN():
@staticmethod
def create_model():
return "This is KN Model"
@classmethod
def classifier(cls):
arg = cls.create_model()
我在那里create_model
创建了一个静态函数,让返回字符串值,而不是使用print
。
或者,既然您正在创建实例,那么您也可以使用这些常规方法:
class KN():
def create_model(self):
return "This is KN Model"
def classifier(self):
arg = self.create_model()
但是,我担心你正在接近来自Java或C#的Python。如果是这样,那么确实知道术语static
在Python中具有不同含义;您没有在此处定义每类数据和方法。您通常使用类属性和类方法,而在其他语言中,您可以使用static
。
Python也没有隐私模型,这使得嵌套类能够共享对父类内部工作的访问。如果你想创建一个嵌套的命名空间,在Python中你通常会使用 modules ,此时Classifiers
将是一个包,KN
和RF
每个包含普通函数的模块(因此create_model
将成为classifier
将调用的另一个全局函数。
答案 1 :(得分:0)
您使用@staticmethod
作为分类器。这样,您告诉Python可以从KN实例调用此函数,但该函数本身并不知道KN类中的其他函数。
答案 2 :(得分:0)
您可能会对&#34;静态&#34;。
的含义感到困惑
静态成员是该类的所有实例共享的成员。因此,当您使用@staticmethod
修饰方法时,此方法将由您的类的所有实例共享。因此,创建kn
对象然后调用kn.classifier()
实际上没有意义,因为classifier
并非旨在对KN
的特定实例执行操作。
从技术上讲,Python错误是因为你在self
方法中引用了KN.classifier
这个问题,但你没有告诉他self
是什么。
相反,实例方法将self
作为第一个参数,因此Python知道self
引用的内容。
关于你对rf.classifier()
的调用有效的原因,我的猜测是Python中实际上并不存在静态方法(你用装饰器声明它们,但装饰器首先不存在)。因此,编写rf.classifier
会对classifier
类中的方法RF
执行调用。因此,您正在调用classifier
方法,该方法确实存在,并且实际上可以运行没有提及self
。