假设我有一组这样的类:
class User(object):
def __init__(self, profile):
# ...
pass
@classmethod
def create_user(cls):
profile = Profile()
user = cls(profile)
class Profile(object):
pass
class SpecialUser(User):
pass
class SpecialProfile(Profile):
pass
每当我想要对 User
或 Profile
进行子类化时,我都需要对它们进行子类化,因为使用上面的代码,如果我执行 SpecialUser. create_user()
它将是一个特殊用户,但具有常规配置文件。
最简单的解决方法是在User
内部创建一个可重写的工厂函数,以创建适当的Profile
。然而,这可能有点乏味。如果用户有一个个人资料并且喜欢其他 10 个类别怎么办?我是否必须重写每个工厂函数?如果其他类也相互引用怎么办?所有这些类都需要工厂函数吗?
我考虑过做这样的事情:
class UserClasses(object):
class User(object):
def __init__(self, profile):
# ...
pass
@classmethod
def create_user(cls):
profile = cls.__parent__.Profile()
user = cls(profile)
class Profile(object):
pass
class SpecialUserClasses(UserClasses):
class Profile(UserClasses.Profile):
pass
将所有这些类包装在另一个类中意味着,如果我对外部类进行子类化并重写其中一个内部类,则引用该类的任何其他内部类将自动使用被重写的内部类。问题是, __parent__
语法不存在,并且根据我的搜索,内部类没有一种简单的方法来获取其外部类。
如何获得类似 classmethod
的功能,但适用于相关类组?
最佳答案
您不一定需要使用可重写的函数。您可以只拥有一个可重写的属性:
class User(object):
profile_class = Profile
def __init__(self, profile):
# ...
pass
@classmethod
def create_user(cls):
profile = cls.profile_class()
user = cls(profile)
然后子类只需定义自己的 profile_class
属性即可工作。不过,要执行此操作,任何用户类都必须在其相应的配置文件类之后定义(因为用户类引用类主体中的配置文件类)。这限制了交叉引用的复杂性。然而,实际上,相互引用的类的复杂系统常常令人困惑且脆弱。
关于Python:子类之间的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32426714/