2014-04-22 98 views
1

我想学习在Python中使用类,并编写了这个测试程序。 它在一定程度上基于我在另一个问题中找到的代码,我在这里找到 Stack OverFlow。Python面向对象编程练习

的代码如下:

class Student(object): 
    name = "" 
    age = 0 
    major = "" 

    # The class "constructor" - It's actually an initializer 
    def __init__(self, name, age, major): 
     self.name = name 
     self.age = age 
     self.major = major 
    def list_values(): 
     print "Name: ", self.name 
     print "Age: ", self.age 
     print "Major: ", self.major 

def make_student(name, age, major): 
    student = Student(name, age, major) 
    return student 

print "A list of students." 
Steve = make_student("Steven Schultz",23,"English") 
Johnny = make_student("Jonathan Rosenberg",24,"Biology") 
Penny = make_student("Penelope Meramveliotakis",21,"Physics") 
Steve.list_values() 
Johnny.list_values() 
Penny.list_values() 

当我运行此,得到错误 “类型错误:list_values()不带任何参数(1给出)”。 在我oppinion我没有给任何参数,但是我去掉括号,给 代码

Steve.list_values 
Johnny.list_values 
Penny.list_values 

这使得没有任何错误,但不会做任何事情 - 没有东西打印出来。

我的问题:

  1. 什么是与括号内的交易?
  2. 与打印报表有什么关系?

回答

1

的Python需要你明确的self参数添加到成员函数,你忘了添加self给你的函数decleration:

def list_values(self): 

这其定义为Student类的成员函数。见here。当您将函数作为Student实例的成员调用时,将隐式添加self变量,因此会触发异常,因为您没有定义接收一个参数的名为list_values的函数。

至于删除括号,这意味着你不是调用函数,而是只引用函数对象,什么都不做。

+0

这是什么意思?它有任何实际用途吗? – user2536262

+0

假设你的意思是'self'变量 - ebarr给出了一个指向Guido(启动python的人)的链接。检查出来:http://neopythonic.blogspot.com.au/2008/10/why-explicit-self-has-to-stay.html – WeaselFox

+0

这是interresting,但实际上我的意思是另一件事,我只是提到没有执行它们的函数名称?这似乎非常奇怪。 – user2536262

0

def list_values():应该是:def list_values(self):

在Python,实例方法采取self作为第一个参数。

0

正如其他人所说,你应该在list_values使用self

但是,您应该真正定义magic method__str____repr__之一。此外,您正在设置一些不必要的class properties

一个更简单的实现是:

class Student(object): 

    def __init__(self, name, age, major): 
     self.name = name 
     self.age = age 
     self.major = major 

    def __str__(self): 
     fs = "<name: {}, age: {}, major: {}>" 
     return fs.format(self.name, self.age, self.major) 

使用方法如下:

In [9]: Steve = Student("Steven Schultz", 23, "English") 

In [10]: Johnny = Student("Jonathan Rosenberg", 24, "Biology") 

In [11]: Penny = Student("Penelope Meramveliotakis", 21, "Physics") 

In [12]: print Steve 
<name: Steven Schultz, age: 23, major: English> 

In [13]: print Johnny 
<name: Jonathan Rosenberg, age: 24, major: Biology> 

In [14]: print Penny 
<name: Penelope Meramveliotakis, age: 21, major: Physics> 

既然你不能定义特殊方法,你不妨用一个named tuple

In [16]: from collections import namedtuple 

In [17]: Student = namedtuple('Student', ['name', 'age', 'major']) 

In [18]: Steve = Student("Steven Schultz", 23, "English") 

In [19]: print Steve 
Student(name='Steven Schultz', age=23, major='English') 
+0

不挑剔,但问题是关于python中的OOP,你的答案是关于避免类的方面,或使用先进的方法,如铸造字符串。 – WeaselFox

+0

@WeaselFox使用'__str__'不是“高级”。它是* pythonic *,如“应该有一个 - 并且最好只有一个 - 明显的方法来做到这一点”。而面向对象并不是一个全能的和最终的。有很多情况下它不合适。请参阅Jack Diederich的优秀视频[“停止写作课程”](http://www.youtube.com/watch?v=o9pEzgHorH0)。 –

+0

我同意你说的话,但在问题的背景下,它不是真正相关的恕我直言。操作系统声称他正试图在Python中学习OOP,并且'__str__'不是您首先要做的第一件事。 – WeaselFox