为什么静态方法不能在实例方法中调用?

时间:2017-06-07 07:49:42

标签: python

错误说全局名称" get_words"没有定义。但我确实定义了一个名为get_words的静态方法。如果我想在train()

中调用get_words函数,我该怎么办?
class classfier(object):
    def __init__(self):
        self.fc = {}
        self.cc = {}

    @staticmethod
    def get_words(item):
        words = re.split(r"\W+",item.strip())
        words =  [element.lower() for element in words if len(element)>2 and len(element)<20]
        return set(words)

    def train(self,item,cat):
        features = get_words(item)
        for f in features:
            self.incf(f,cat)
        self.incc(cat)

3 个答案:

答案 0 :(得分:0)

除了实例和类都不是第一个参数之外,staticmethods与instancemethods或classmethods没有区别:它们是类的属性,并且相同的查找规则适用于任何其他属性查找。 IOW:你必须在类或它的实例上查找它。由于您在实例方法中进行调用,因此显而易见的事情是查找实例,即:

def train(self,item,cat):
    features = self.get_words(item)

使用原始代码(features = get_words(...)),Python将首先查找本地名称(函数体的本地名称),然后查找全局(模块级别)名称 - 并使用如果没有找到任何名称错误。请记住,在Python中,一切都是对象(包括函数,类和模块),因此所有内容都共享相同的命名空间和查找规则。

答案 1 :(得分:-1)

在实例内部调用静态方法需要将Class的名称作为标识符:

features = classfier.get_words(item)

会奏效。 self总是引用对象或实例本身,类或静态方法或值可以由类名调用。

答案 2 :(得分:-1)

在C ++中

<div class="header">
  <select name="dropdown" id='target'>
<option value="temp1" value2="form1">option1</option>
<option value="temp2" value2="form2">option2</option>
</select>
</div>

<div class="temps">
  <div id="temp1" class="initial">
    <?php include "temp1.php"; ?>
  </div>
  <div id="temp2" class="initial">
    <?php include "temp2.php"; ?>
  </div>
</div>

<div class="forms">
  <div id="form1" class="initial">
    <?php include "form1.php"; ?>
  </div>
  <div id="form2" class="initial">
    <?php include "form2.php"; ?>
  </div>
</div>

在Java中 -

class Something
{
private:
    static int s_value;
public:
    static int getValue() { return s_value; } // static member function
};

int Something::s_value = 1; // initializer

int main()
{
    std::cout << Something::getValue() << '\n';
}

最后是在Python中 -

class Student9{  
 int rollno;  
 String name;  
 static String college = "ITS";  

 static void change(){  
 college = "BBDIT";  
 }  

 Student9(int r, String n){  
 rollno = r;  
 name = n;  
 }  

 void display (){System.out.println(rollno+" "+name+" "+college);}  

public static void main(String args[]){  
Student9.change();  

Student9 s1 = new Student9 (111,"Indian");  
Student9 s2 = new Student9 (222,"American");  
Student9 s3 = new Student9 (333,"China");  

s1.display();  
s2.display();  
s3.display();  
}
}

随处查看我们使用类名来调用静态方法!这里有documentation

给你的东西
  

返回函数的静态方法。

     

静态方法不会收到隐含的第一个参数。至   声明一个静态方法,使用这个成语:

     

C类(对象):       @staticmethod       def f(arg1,arg2,...):           ... @staticmethod表单是一个函数装饰器 - 请参阅函数定义中的函数定义说明   的信息。

     

可以在类(例如C.f())或实例上调用它   (例如C()。f())。除了类之外,该实例将被忽略。

     

Python中的静态方法与Java或C ++中的静态方法类似。   另请参阅classmethod()以获取对创建有用的变体   备用类构造函数。

     

有关静态方法的更多信息,请参阅文档   标准类型层次结构中的标准类型层次结构。

     

2.2版中的新功能。

     

在版本2.4中更改:添加了函数装饰器语法。

正如评论中所提到的,当您从类实例方法外部调用静态方法时,这应该是您应该做的。但是,如果要从类的实例方法中调用静态方法,那么使用self可能是最好的想法,让解释器为您解析引用。对不起有点困惑。我试图提供三种语言之间的比较,并尝试解释事情,但有点错过了一点主要观点。