为什么我在 class 上得到一个 AttributeError,即使我用那个名字定义了一个方法?

Why do I get an AttributeError on a class, even though I defined a method with that name?

我正在学习 "intro to object-oriented programming" class,我正在学习 Think Python 的第 17 章。下面的代码难倒了我。当 运行 时,我一直得到 "AttributeError: 'Time' object has no attribute 'print_time'",但我很难弄清楚。有人可以帮助分解我做错了什么并帮助我更好地解释一下吗?

class Time(object):
    """represents the time of day.  attributes: hour, minute, second"""

def print_time(time):
    print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)

start = Time()

start.hour = 9
start.minute = 45
start.second = 00

print_time(start)

class Time(object):
    def print_time(time):
        print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)

start.print_time()

我读到这是一个缩进错误,但我已将 IDLE 设置为警告我冲突,并已检查两次无济于事。

我不这样做 Python,但我会从良好的错误消息中猜测您正在尝试调用对象类型不存在的方法。

这一行(最后):

start.print_time()

可能应该用这样的东西代替:

print_time(start)

让我们一次(咳嗽)一步地检查您的代码。

class Time(object):
    """represents the time of day.  attributes: hour, minute, second"""

在这里,您定义了一个 class Time. It has a docstring,但没有方法或其他属性。

def print_time(time):
    print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)

这是一个 function,与您之前定义的 Time class 完全不同,它接受参数 time 并尝试使用 [= 打印字符串24=] 的 hourminutesecond 属性。如果 time 没有所有这些属性,您将收到错误消息。

start = Time()

这将创建一个名为 startTime 对象。

start.hour = 9
start.minute = 45
start.second = 00

这些行将 hourminutesecond 属性添加到 start

print_time(start)

这会以 start 作为参数调用 print_time,结果输出:

09:45:00

到目前为止一切顺利。现在...

class Time(object):
    def print_time(time):
        print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)

这创建了一个 new class,它恰好也被称为 Time。这次它没有文档字符串,但它确实有一个名为 print_timemethod(它与定义的 print_time 函数 完全分开更早,尽管它具有相同的名称和代码)。

重要的是要意识到,仅仅因为您创建了一个名为 Time 的新 class, 根本没有任何效果 在您使用先前定义的 class 创建的对象上。它们仍然是您定义的 original Time class 的实例。使用内置 help 函数很容易证明这一点:

>>> help(start)
Help on Time in module __main__ object:

class Time(__builtin__.object)
 |  represents the time of day.  attributes: hour, minute, second
 |  
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
start.print_time()

请注意 help 向您显示原始 Time class 中的文档字符串,而不是新版本中的方法。

>>> help(Time)
Help on class Time in module __main__:

class Time(__builtin__.object)
 |  Methods defined here:
 |  
 |  print_time(time)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

... 而这显示了新 Time class 中的 print_time 方法,但不是原始方法中的文档字符串。

一种思考方式是 class 就像一个制造物体的工厂 – 拆除福特工厂然后在同一个地方建造一个新工厂对它没有任何影响'71 野马已经停在你的车道上了。

如果您想要 new Time class 的实例,您必须创建它:

>>> restart = Time()

...然后,一旦它具有正确的属性...

>>> restart.hour = 9
>>> restart.minute = 45
>>> restart.second = 00

...你将能够成功调用它的print_time方法:

>>> restart.print_time()
09:45:00