这是最简单的示例:
class Foo():
def five(self):
return 5
def bar():
print Foo.five()
如您所见,我想从five
调用bar
,但是问题是类方法采用self
作为参数。
我通过将Foo实例一直输入到bar来解决了这个问题,如下所示:
class Foo():
def five(self):
return 5
def bar(instance_of_Foo):
print Foo.five(instance_of_Foo)
foobar = Foo()
bar(foobar)
此解决方案可以正常工作,因为我可以将Foo
的实例输入到对bar()
的调用中。问题在于,在实例化bar()
之前需要调用Foo
,因为Foo
对象是线程的目标。
下面是一个更复杂的示例,演示了该问题:
from tkinter import *
import threading
import time
count = 0
def counter():
global count
while True:
count += 1
print count
time.sleep(1)
class GUI():
def __init__(self):
self.root = Tk()
def five(self):
global count
self.var = StringVar()
self.var.set(count)
self.label = Label(self.root, textvariable=self.var)
self.label.pack()
self.root.mainloop()
def update_gui():
global count
while True:
GUI.var = count
GUI.root.update()
threads = []
t = threading.Thread(target=update_gui)
threads.append(t)
t.start()
countbot = threading.Thread(target=counter)
threads.append(countbot)
countbot.start()
foobar = GUI()
foobar.five()
以上抛出此错误:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Henry/documents/python/blank3.py", line 36, in update_gui
GUI.root.update()
AttributeError: class GUI has no attribute 'root'
这真的让我感到惊讶,因为GUI确实具有一个名为root的属性。
答案 0 :(得分:3)
您需要做的就是将函数标记为类方法:
class Foo():
@classmethod
def five(cls):
return 5
def bar():
print Foo.five()
答案 1 :(得分:3)
首先,由于您既不依赖类也不依赖实例,所以简单的解决方案是make your method a static method:
class Foo():
@staticmethod
def five():
return 5
def bar():
print Foo.five()
A class method也可以使用,但是除非有某些特定类的行为要根据可能的子类来更改(从已知子类中被调用的子类中派生信息),否则它是没有意义的。实际上,@classmethod
实际上仅适用于备用构造函数,不适用于此处。
第二,在您的代码示例中,Foo
没有名为self
的属性,因为您从未构造过Foo
的实例,因此从未调用__init__
来分配class属性。如果您想执行类似的操作来使单例实例正常工作,请不要在__init__
中执行;定义类后立即执行操作,例如:
class Foo():
...
Foo.singleton = Foo()
同样,它不是特别有用,因此,如果可能的话,我会避免使用它。