如何将实例强制转换为派生类?

Chr*_*ieb 11 python oop inheritance

我正在尝试在我正在使用的Python程序中使用一点继承.我有一个基类User,它实现了用户的所有功能.我添加了一个未经批准的用户的概念,就像用户一样,增加了一个方法.

User类有一些返回User对象的方法.当我进行子类化时,这将不起作用,因为我最终会让UnapprovedUser返回一个User,阻止我调用此方法等等.

class User(object):
    base_dn = 'ou=Users,dc=example,dc=org'

    @classmethod
    def get(cls, uid):
        ldap_data = LdapUtil.get(uid + ',' + self.base_dn)
        return User._from_ldap(ldap_data)

class UnapprovedUser(User):
    base_dn = 'ou=UnapprovedUsers,dc=example,dc=org'

    def approve(self):
        new_dn = '' # the new DN
        LdapUtil.move(self.dn, new_dn)
Run Code Online (Sandbox Code Playgroud)

两个类的get()_from_ldap()方法相同,但get()UnapprovedUser中的方法需要返回UnapprovedUser对象,而不是User.

如何将我获得的User的一个实例User.get()转换为UnapprovedUser?

我想做的事情如下:

class UnapprovedUser(User):
    # continued from before

    @classmethod
    def get(cls, uid):
        user = super(UnapprovedUser, cls).get(uid)
        return (UnapprovedUser) user # invalid syntax
Run Code Online (Sandbox Code Playgroud)

这样我就可以从父进程中包装该方法,并简单地将返回的值强制转换为正确的类.然后,这样做可能导致父母使用他们的价值self.base_dn,这将打破一切.

Lau*_*ves 9

而不是"投射",我认为你真的想要创建一个UnapprovedUser而不是User在调用时UnapprovedUser.get().要做到这一点:

更改User.get为实际使用cls传入的参数:

@classmethod
def get(cls, uid):
    ldap_data = LdapUtil.get(uid + ',' + self.base_dn)
    return cls._from_ldap(ldap_data)
Run Code Online (Sandbox Code Playgroud)

你需要做类似的事情_from_ldap.您没有列出代码_from_ldap,但我认为在某些时候它会执行以下操作:

result = User(... blah ...)
Run Code Online (Sandbox Code Playgroud)

您想要将其替换为:

result = cls(... blah ...)
Run Code Online (Sandbox Code Playgroud)

请记住:在Python中,类对象是一个可调用的,用于构造该类的实例.因此,您可以使用clsclassmethod 的参数来构造用于调用classmethod的类的实例.