【问题标题】:python unbound method again再次python未绑定方法
【发布时间】:2009-12-15 11:51:28
【问题描述】:

这让我陷入了困境(对不起,我对 python 还是很陌生) 感谢您的任何帮助。

错误

print Student.MostFrequent() TypeError: unbound method

MostFrequent() 必须使用 学生实例作为第一个参数 (一无所获)

这个Student.MostFrequent()在最后(最后一行)被调用,def是类中的最后一个def

已编辑 - 命名约定

我的长代码

import csv
class Student:
    sports = []
    ftopics = []
    stopics = []
    choice_list = []
    choice_dict = {}
    def __init__(self, row):
       self.lname, self.fname, self.ID, self.gender, self.sport, self.movie, self.movieyr, self.country, self.ftopic, self.stopic = row
       self.sports.append(self.sport)
       self.ftopics.append(self.ftopic)
       self.stopics.append(self.stopic)
    def print_information(self):
       return (self.lname, self.fname, self.ID, self.gender)
    def print_first(self):
       return (self.lname, self.fname, self.sport)
    def print_second(self):
        return (self.lname, self.fname, self.movie, self.movieyr)
    def print_third(self):
        return (self.lname, self.fname, self.country)
    def print_fourth(self):
        return (self.lname, self.fname, self.ftopic, self.stopic)
    def most_frequent(self):
        for choice in self.choice_list:
                self.choice_dict[choice] = self.choice_dict.get(choice, 0) + 1
        self.mostFrequent = sorted([(v, k) for k, v in self.choice_dict.items()], reverse=True)
        print self.mostFrequent

reader = csv.reader(open('new_mondy_csc_data_revise.csv'), delimiter=',', quotechar='"')
header = tuple(reader.next())
print "%-17s|%-10s|%-6s|%s" %header[:4]
print "-" * 45
students = list(map(Student, reader)) # read all remaining lines
for student in students:
    print "%-17s|%-10s|%-6s|%3s" % student.print_information()

print "%-17s|%-10s|%s" %(header[0],header[1],header[4])
print "-" * 45
for student in students:
    print "%-17s|%-10s|%s" %student.print_first()

print "%-17s|%-10s|%-16s|%s" %(header[0],header[1],header[5],header[6])
print "-" * 45
for student in students:
    print "%-17s|%-10s|%-16s|%s" % student.print_second()

print "%-17s|%-10s|%s" %(header[0],header[1],header[7])
print "-" * 45
for student in students:
    print "%-17s|%-10s|%s" %student.print_third()

print "%-17s|%-10s|%-15s|%s" %(header[0],header[1],header[8],header[9])
print "-" * 45
for student in students:
    print "%-17s|%-10s|%-16s|%s" % student.print_fourth()

k = len(students)    
# Printing all sports that are specified by students
for s in set(Student.sports): # class attribute
    print s, Student.sports.count(s), round(((float(Student.sports.count(s)) / k) *100),1)

# Printing sports that are not picked 
allsports = ['Basketball','Football','Other','Baseball','Handball','Soccer','Volleyball','I do not like sport']
allsports.sort()
for s in set(allsports) - set(Student.sports):
    print s, 0, '0%'
Student.choice_list = Student.sports
X = Student()
X.most_frequent()

#class Search(Student):
#    def __init__(self):
#        Student.__init__

【问题讨论】:

    标签: python class


    【解决方案1】:

    首先阅读PEP-8关于命名约定:

    方法名称和实例变量

      Use the function naming rules: lowercase with words separated by
      underscores as necessary to improve readability.
    

    second您在 Student 类上调用 mostFrequest,而不是它的实例。改为在实例上使用该方法:

    student = Student(row)
    student.MostFrequent()
    

    【讨论】:

      【解决方案2】:

      使用Student().MostFrequent()

      编辑

      注意你使用类属性,这是危险的。这里是一个例子:

      >>> class Person:
      ...  name = None
      ...  hobbies = []
      ...  def __init__(self, name):
      ...   self.name = name
      ... 
      >>> a = Person('marco')
      >>> b = Person('francesco')
      >>> a.hobbies.append('football')
      >>> b.hobbies
      ['football']
      >>> a.name
      'marco'
      >>> b.name
      'francesco'
      >>> a.name = 'mario'
      >>> b.name
      'francesco'
      >>> a.name
      'mario'
      >>> 
      

      如你所见,我修改了 marco 的爱好,而 francesco 的爱好也随之改变。

      【讨论】:

      • 这是否适用于构造函数,例如:def __init__(self, row)?
      • 以及史蒂夫怎么说从方法定义中删除最常见的参数,但你得到的错误与你没有实例化类有关
      • @MYYN:没有。也许我匆忙回答了这个问题,但他得到了那个错误,因为他在一个类而不是一个对象上调用了一个方法。在类上调用方法有classmethodstaticmethod 装饰器。请参阅有关其使用的文档。
      • 这正是我的 django 验证器所需要的,我不想创建验证器类的实例,但 validators = [ValidatorClass().function_name] 是我需要做的!
      【解决方案3】:

      您可能想要的是将most_frequent 定义为classmethod

      @classmethod
      def most_frequent(cls):
          for choice in cls.choice_list:
              cls.choice_dict[choice] = cls.choice_dict.get(choice, 0) + 1
          cls.mostFrequent = sorted([(v, k) for k, v in cls.choice_dict.items()], reverse=True)
          return cls.mostFrequent
      

      【讨论】:

        【解决方案4】:

        首先,我建议只将函数名称设为小写。

        使用MostFrequent 作为静态方法导致的错误。为此,您需要显式传递Student 的实例作为第一个参数。

        如果直接在Student 的实例上调用,该实例将作为第一个参数隐式传递。

        考虑使用 staticmethod 装饰器来静态使用函数。

        【讨论】:

          【解决方案5】:

          您很少在类定义上调用方法 (Student)

          几乎总是你创建一个类的实例

          someStudent = Student(someRow)
          

          然后调用实例(“对象”)上的方法someStudent

          someStudent.MostFrequent()
          

          【讨论】:

            【解决方案6】:

            Student.MostFrequent 表示您正在尝试使用静态方法,而不是实例方法。所以你必须先调用 Student() 创建实例,然后调用 MostFrequent() 。

            P.S.:如果这不是某个神秘项目的一部分,我敦促您遵循 PEP 8 并使用 most_frequent 作为方法名称。

            【讨论】:

              【解决方案7】:

              在你的类定义中,方法定义

              def MostFrequent(self,mostFrequent):
              

              具有您可能不希望出现的额外变量 mostFrequent。尝试更改为:

              def MostFrequent(self):
              

              【讨论】:

              • 我猜在这种情况下,这会抱怨参数数量错误,或者不是?
              • 总是很高兴看到一个穿着时髦的 CS 毕业生
              猜你喜欢
              • 1970-01-01
              • 2010-11-04
              • 2017-11-06
              • 2011-04-03
              • 1970-01-01
              • 2012-11-14
              • 1970-01-01
              • 2011-08-26
              相关资源
              最近更新 更多