Python:在另一个类中定义的类

2024-03-28 16:16:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个可以定义其他类的类。例如,假设您有一个名为“Shapes”的类,通过该类可以创建“Shapes”对象。我想做的是,在“Shapes”中创建其他类,例如,circle或square。每个“子类”都有相同的变量,例如颜色、表面积等。因此,在一天结束时,我想定义一个称为“Tommy”的蓝色圆,其表面积为78.5398163397u^2

在我看来是这样的:

class Shapes():
    def __init__(self, myclassname):
        class myclassname():
            def __init__(self, color, surf_area):
                self.color = color
                self.surf_area = surf_area

因此,要使用它,您可以:

Circle = Shapes(Circle)
Tommy = Circle(blue, 78.5398163397)

我试过了,没用。你知道吗

任何帮助都将不胜感激。你知道吗

谢谢你。你知道吗

编辑:

有些人似乎很困惑,我不想在程序中硬编码一个圆、正方形或三角形类,我希望能够在运行时定义一个新的形状。你知道吗

编辑2:

我不是要继承。基本上我只想给一个类一个变量名,例如

var = Input('Enter class name')
class var(): # var as in the variable not a class called var
    normal class stuff

Tags: self编辑定义initvardefareatommy
3条回答

您必须重写{new}方法,因为{init}不能返回任何值,也可以使用type函数动态构造新类:

class Shapes(object):

    def __new__(cls, class_name):
        def default_init(self, color, surf_area):
            self.color = color
            self.surf_area = surf_area
        return type(class_name, (Shapes,),
                {'__init__': default_init, '__new__': super(Shapes, 
cls).__new__})

# Usage:
Circle = Shapes('Circle')
Tommy = Circle('blue', 78.5398163397)

print vars(Tommy)
# {'color': 'blue', 'surf_area': 78.5398163397}

或者,可以使用通过键指向类的类继承和映射字典来实现相同的行为,但不需要动态创建类:

class Shape(object):
    """ Base class for shapes. """
    pass

class Circle(Shape):
    def __init__(self, color, surf_area):
        self.color = color
        self.surf_area = surf_area

class Triangle(Shape):pass


shapes = {
    'circle': Circle,
    'triangle': Triangle,
}

circle = shapes['circle']('blue', 78.5398163397)

你可以这样做:

class Shape(object):
    _registry = {}
    def __new__(cls, name):
        if name in cls._registry:
            return cls._registry[name]
        class Proto(object):
            def __init__(self, color, surf_area):
                self.color = color
                self.surf_area = surf_area
        Proto.__name__ = name
        cls._registry[name] = Proto
        return Proto

但我一点也不明白-你的“动态”类根本没有行为,所有的类都有完全相同的属性集,所以你可以只使用一个类,而得到完全相同的行为:

class Shape(object):
    def __init__(self, typename, color, surf_area):
        self.typename = typename
        self.color = color
        self.surf_area = surf_area
    def __repr__(self):
        return "<Shape({}) at {}>".format(self.typename, id(self))

blue_circle = Shape("Circle", "blue", 78.4222)

looks like a XY problem对我来说,你也许应该告诉更多关于你试图用这个来解决的真正问题。你知道吗

你正在寻找一个工厂模式。你知道吗

快速谷歌搜索提供:

# Factory/shapefact1/ShapeFactory1.py
# A simple static factory method.
from __future__ import generators
import random

class Shape(object):
    # Create based on class name:
    def factory(type):
        #return eval(type + "()")
        if type == "Circle": return Circle()
        if type == "Square": return Square()
        assert 0, "Bad shape creation: " + type
    factory = staticmethod(factory)

class Circle(Shape):
    def draw(self): print("Circle.draw")
    def erase(self): print("Circle.erase")

class Square(Shape):
    def draw(self): print("Square.draw")
    def erase(self): print("Square.erase")

# Generate shape name strings:
def shapeNameGen(n):
    types = Shape.__subclasses__()
    for i in range(n):
        yield random.choice(types).__name__

shapes = \
  [ Shape.factory(i) for i in shapeNameGen(7)]

for shape in shapes:
    shape.draw()
    shape.erase()

http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Factory.html的学分

相关问题 更多 >