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

作者站长头像
站长
· 阅读数 9

我用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__函数中的内容移到外面来,因为这样会增加创建有类型指针类的难度,原本只需要多重继承一下即可。

回复
1个回答
avatar
test
2024-07-04

已解决,我不应该使用__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
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容