Python:将“尚未定义”的类名作为默认参数
我有一个叫“class1”的类,它需要能够创建一个不同类名的对象。这个类名是通过一个叫“friend”的参数传递进来的。我希望这个“friend”参数默认是一个叫“class2”的类名。
另外,我也需要“class2”有同样的功能。所以“class2”应该把“class1”作为默认的朋友参数:
class class1():
def __init__(self, friend = class2):
self.friendInstance = friend()
class class2():
def __init__(self, friend = class1):
self.friendInstance = friend()
class1()
class2()
现在我遇到了以下错误信息:
def __init__(self, friend = class2):
NameError: name 'class2' is not defined
当然,我不能在“class1”之前定义“class2”,因为这样会导致类似的错误:“class1”没有定义。你知道有什么解决办法吗?
非常感谢你的帮助!
亨利
2 个回答
1
即使你解决了 NameError
的问题,你还会遇到另一个问题——你正在尝试创建一个递归的数据结构。每一个 class1
的实例都会试图 创建 一个 class2
的实例,而这个 class2
的实例又会试图 创建 另一个 class1
的实例,依此类推,永无止境(实际上只会持续到你遇到 RuntimeError: maximum recursion depth exceeded
的错误)。
在不了解你具体想做什么的情况下,这里有一个简单的解决方案:
class class1(object):
def __init__(self, friend=None):
if friend is None:
friend = class2(self) # create a class2 instance with myself as a friend
self.friendInstance = friend
class class2(object):
def __init__(self, friend=None):
if friend is None:
friend = class1(self) # create a class1 instance with myself as a friend
self.friendInstance = friend
print class1()
# <__main__.class1 object at 0x00B42450>
print class2()
# <__main__.class2 object at 0x00B65530>
4
你可以把它推迟到后面再处理:
class class1(object):
def __init__(self, friend=None):
if friend is None:
friend = class2
self.friendInstance = friend()
补充:其实,不要这样做。这样会创建一个class2的实例,然后这个实例又会创建一个class1的实例,接着这个class1的实例又会创建一个class2的实例,依此类推。也许你真的想传入一个实例,而不是要实例化的类:
class class1(object):
def __init__(self, friend=None):
if friend is None:
self.friendInstance = class2(self)
else:
self.friendInstance = friend
class2也是一样。这种方法虽然不够灵活,但相对简单。如果你真的想要更灵活的方式,可以试试这样:
class class1(object):
def __init__(self, friend=None, friendClass=None):
if friend is None:
self.friendInstance = (class2 if friendClass is None else friendClass)(self)
else:
self.friendInstance = friend
class class2(object):
def __init__(self, friend=None, friendClass=class1):
if friend is None:
self.friendInstance = friendClass(self)
else:
self.friendInstance = friend
这可以通过继承或元类来简化,但你大概明白我的意思了。