我要怎么修改一个被导入的类?

我要怎么修改一个被导入的类?

我用python制作了一个指针类,只要将这个类作为第一个类继承,类型类作为第二个类继承,就可以实现有语法提示的指针,但现在有一个问题,我在实例化的时候用type函数重新生成了一个类,导致这个类的实例类型不等于这个类,我要怎么办?

  • Pointer

    def fun_(_fun_):

    def fun__(self_, *args_, **kwargs_):

    return _fun_(self_.__value__, *args_, **kwargs_)

    return fun__

    class Pointer:

    __TypePointer = {}

    __dir = ['__class__', '__new__', '__init__', '__getattribute__', '__setattr__']

    def __new__(cls, *args, **kwargs):

    bases = cls.__bases__

    if bases[0] != Pointer:

    raise TypeError('Pointer需要作为第一个被继承的父类')

    if len(bases) == 1:

    return super().__new__(cls)

    elif len(bases) == 2:

    class_ = cls.__bases__[1]

    else:

    raise TypeError('只能设置一个类型作为指针类型')

    if cls.__name__ not in cls.__TypePointer:

    p = type(cls.__name__, (Pointer,), {'__type__': class_, '__value__': class_()})

    for name in dir(class_):

    if name in cls.__dir:

    continue

    if name[:2] == name[-2:] == '__':

    fun = getattr(class_, name)

    if callable(fun):

    setattr(p, name, fun_(fun))

    cls.__TypePointer[cls.__name__] = p

    else:

    p = cls.__TypePointer[cls.__name__]

    p = p(*args, **kwargs)

    return p

    def __init__(self, value=None):

    self.__value__ = value

    def __getattribute__(self, item):

    if item == '__value__':

    return super().__getattribute__('__value__')

    if item == '__type__':

    return super().__getattribute__('__type__')

    return getattr(super().__getattribute__('__value__'), item)

    def __setattr__(self, item, value):

    if item == '__value__':

    if type(value) == self.__type__:

    super().__setattr__('__value__', value)

    else:

    raise ValueError('类型不匹配')

    else:

    setattr(super().__getattribute__('__value__'), item, value)

    class StrPointer(Pointer, str):

    pass

  • test.py

    from Pointer import StrPointer

    s = StrPointer('a')

    print(type(s), StrPointer)

    print(type(s) == StrPointer)

  • 输出

    <class 'Pointer.StrPointer'> <class 'Pointer.StrPointer'>
    False

我知道为什么,但我没法解决。我不希望将__new__函数中的内容移到外面来,因为这样会增加创建有类型指针类的难度,原本只需要多重继承一下即可。


回答:

已解决,我不应该使用__new__方法,而应该使用__init_subclass__方法

class Pointer:

def __init_subclass__(cls, **kwargs):

bases = tuple(set(cls.__bases__) - {Pointer})

assert len(bases) <= 1, '只能再继承一个类'

assert len(bases), '必须再继承一个类'

bases = bases[0]

for fun_name in dir(cls):

if fun_name not in not_transfer_fun and callable(getattr(cls, fun_name)):

setattr(cls, fun_name, fun_transfer(getattr(cls, fun_name)))

cls.__init__ = __init__

cls.__setattr__ = __setattr__

cls.__getattribute__ = __getattribute__

cls.__value__ = None

print(cls.__class__)

cls.__class__ = cls

cls.__type__ = bases

return cls


回答:

new应该作为元类使用

  1. StrPointer的实例肯定是str, 但是它的类型也匹配Pointer
  2. type(s), StrPointer两个不相等的原因就是s已经不是StrPointer的实例
  3. isinstance的调用是在元类__instancecheck__方法里面
  4. type的机制得从cpython源码找

以上是 我要怎么修改一个被导入的类? 的全部内容, 来源链接: utcz.com/p/938865.html

回到顶部