是否可以从作为参数给出的类继承?

我有几个类,就像对待数据的容器一样(图表示)。它们都有相同的@staticmethod,例如get_edges()get_vertices()。我想通过给定参数导入指定的图形类。我现在要做的是:

class Figure:
    def __init__(self,figure_type):
        exec('import figures.' + figure_type.lower())
        self.element = eval('figures.' + figure_type.lower() + '.' + figure_type)()

    def create(self,vertices):
        glBegin(GL_LInes)
        for edge in self.element.get_edges():
            for vertex in edge:
                glColor3fv((0.5,0))
                glVertex3fv(vertices[vertex])
        glEnd()

class Cube:

    @staticmethod
    def get_edges():
        return ((0,1),(0,3),4),(2,7),(6,(5,7))

我想知道是否有办法得到类似的东西:

class Figure(figure_type):
    def __init__(self,figure_type):

仅能使用self.get_edges(),而不是self.element.get_edges()。我怎么才能得到它?甚至有可能吗?

fishtreerain 回答:是否可以从作为参数给出的类继承?

您的设计看起来像是在制作mixins。这是一个可以动态生成mixins的类工厂玩具示例。


figures.py

data = ((0,1),(0,3),4),(2,7),(6,3))

class FT:
    @staticmethod
    def ge():
        return data

class FT1:
    @staticmethod
    def ge():
        return [(x*x,y*y) for x,y in data]

def compose(ftype):
    '''Returns a class composed of F and ftype.'''
    return type(f'F_{ftype.__name__}',(F,ftype),{})

some_module.py:

import importlib

class F:
    def __init__(self):
        self.x = 'foo'
    def a(self):
        s = '|'.join(f'{thing}' for thing in self.ge())
        return s
    def b(self):
        return 'baz'

def compose(ftype):
    cls = getattr(importlib.import_module('figures'),ftype)
    return type(f'F_{ftype}',cls),{})


z = compose('FT')()
y = compose('FT1')()

两个对象都具有相同的b方法。

>>> z.b(),y.b()
('baz','baz')

两者都使用来自特定a方法的数据的相同ge方法

>>> print(z.a())
(0,1)|(0,3)|(0,4)|(2,1)|(2,3)|(2,7)|(6,3)
>>> y.a()
'(0,9)|(0,16)|(4,1)|(4,9)|(4,49)|(36,9)'

每个对象都有特定的ge方法

>>> z.ge()
((0,3))
>>> y.ge()
[(0,9),16),(4,49),(36,9)]
>>> 

zy是不同类的实例。

>>> z.__class__,y.__class__
(<class '__main__.F_FT'>,<class '__main__.F_FT1'>)
>>> 

组成类的多个实例。

>>> One = compose(FT)
>>> q,r,s = One(),One(),One()
>>> q,s
(<__main__.F_FT object at 0x0000000003163860>,<__main__.F_FT object at 0x000000000D334198>,<__main__.F_FT object at 0x000000000D334828>)
>>>

如果一切在同一模块中,则compose变为

def compose(ftype):
    return type(f'F_{ftype.__name__}',{})

z = compose(FT)
y = compose(FT1)

What is the difference between a mixin and inheritance?


使用抽象基类的类似解决方案。 -除非实例化G,否则 ge被覆盖。

import importlib
import abc

class G(abc.ABC):
    def __init__(self):
        self.x = 'foo'
    def a(self):
        s = '|'.join(f'{thing}' for thing in self.ge())
        return s
    def b(self):
        return 'baz'

    @staticmethod
    @abc.abstractmethod
    def ge():
        pass

# either of these work
def new(ftype):
    cls = getattr(importlib.import_module('figures'),ftype)
    return type(cls.__name__,(cls,G),{})
#def new(ftype):
#    cls = getattr(importlib.import_module('figures'),ftype)
#    return type(cls.__name__,(G,),{'ge':staticmethod(cls.ge)})
#usage
# A = new('FT')

与其他类似,除了特定的 static 方法只是普通函数,并且从上方使用ABC

def FT_ge():
    return ((0,3))
def other_new(f):
    return type(f.__name__.split('_')[0],{'ge':staticmethod(f)})
# usage
# B = other_new(FT_ge)
,

您可以使用importlib.import_module导入模块。但是,建议从基类继承这些类,该基类使用元类来跟踪其子类并在字典中进行映射。然后,您可以将此基类用作抽象来与所有子类Track subclasses in python

进行交互
本文链接:https://www.f2er.com/3132741.html

大家都在问