开发者

python unbound method again

This gets me into difficult time (sorry, i am still very new to python) Thank you for any kind of help.

The error

print Student.MostFrequent() TypeError: unbound method

MostFrequent() must be called with Student instance as first argument (got nothing instead)

This Student.MostFrequent() is called all the way in the end (last line) and the def is last def in the class

EDITED - Naming convention

My long code

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):
 开发者_StackOverflow      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__


first read PEP-8 on naming conventions:

Method Names and Instance Variables

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

second you are calling mostFrequest on the class Student, not an instance of it. Use the method on an instance instead:

student = Student(row)
student.MostFrequent()


use Student().MostFrequent()

edit:

beware that you use class attributes and this is dangerous. here an example:

>>> 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'
>>> 

as you can see i modify marco's hobbies and francesco's hobbies are modified consequentially.


What you probably want is to define most_frequent as a 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


First, I recommend making function names lower case only.

The error you get results from the usage of MostFrequent as a static method. For this to work, you need to explicitly pass an instance of Student as first argument.

If called directly on an instance of Student, the instance will implicitly be passed as first argument.

Consider using the staticmethod decorator for static usage of functions.


You only rarely call methods on a class definition (Student)

Almost always, you create an instance of the class

someStudent = Student(someRow)

Then you call the method on the instance ("object"), someStudent.

someStudent.MostFrequent()


Student.MostFrequent means You're trying to use static method, not instance method. So You must first create instance by calling Student() and then call MostFrequent() on it.

P.S.: If this is not part of some arcane project, I urge you to follow PEP 8 and use most_frequent as method name.


in your class def, the method definition

def MostFrequent(self,mostFrequent):

has the extra variable mostFrequent that you probably don't want there. Try changing to :

def MostFrequent(self):
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜