繁体   English   中英

如何在运行时使用python动态创建新的类实例?

[英]How to create new class instances dynamically at runtime in python?

我正在尝试解决这个问题:

想象一下(文字)一叠盘子。 如果堆栈太高,可能会倾倒。 因此,在现实生活中,当前一个堆栈超过某个阈值时,我们可能会启动一个新的堆栈。 实现一个模仿它的数据结构SetOfStacks。 SetOf-Stacks应该由几个堆栈组成,并且一旦前一个堆栈超过容量,就应该创建一个新的堆栈。 SetOfStacks.push()和SetOfStacks.pop()的行为应与单个堆栈相同(也就是说,pop()返回的值应与仅有单个堆栈时的值相同)。 奖励:实现一个函数popAt(int index),该函数在特定的子堆栈上执行弹出操作。

所以我写了代码:

#!/bin/env python

from types import *

class Stack:

    def __init__(self):
        self.items = []
        self.capacity = 3
        self.stackscount = 0

    def create(self):
        id = self.stackscount + 1
        id = str(id) + "_stack"
        # How to create a new instance of Stack class at runtime ?
        # the __init__ must be run too.

    def push(self, item):
        if self.size() <= self.capacity:
            self.items.append(item)
        else:
            self.create()

    def pop(self):
        return self.items.pop()

    def popAt(self):
        pass

    def peek(self):
        return self.items[len(self.items)-1]

    def size(self):
        return len(self.items)

s = Stack()
s.push(10)

如何在运行时动态创建新的s类型对象? 我在互联网上搜索,发现使用new.instance或new.classobj是解决方案,但是当我这样做时,我的新对象似乎没有__init__函数中的items 在python3中, type()似乎是答案,但是该文档没有任何示例。

您通过引用“类型对象”感到困惑。 在Python中,这意味着类本身,而不是其实例。

要创建新的Stack对象,只需执行您已经在做的事情:调用Stack类。 您可以将它们附加到列表中:

stacks = [Stack() for _ in range(5)]

但是,正如jon所指出的那样,由于您尚未定义SetOfStacks类,因此无法解决您的问题。

type()函数确实是您要寻找的。 可以在这里找到文档: https : //docs.python.org/2/library/functions.html#type

您可以这样称呼它:

# Bases is a tuple of parent classes to inherit
bases = Stack,

# Dict contains extra properties for the class, for example if you want to add a class variable or function
dict_ = {}

# Construct the class
YourClass = type('YourClass', bases, dict_)

# Create an instance of the class
your_instance = YourClass()

看来您只是在查看实例创建:

class Stack(object):

    def create(self):
        id = self.stackscount + 1
        id = str(id) + "_stack"
        # How to create a new instance of Stack class at runtime ?
        # the __init__ must be run too.
        stack = Stack()

您可以简单地使用父子关系:当堆栈已满时,它将创建一个子级并委托下一次推送。 它可能导致:

class Stack:

    def __init__(self, parent = None, id=None):
        self.stackscount = 0
        self.capacity = 3
        self.items = []
        self.parent = parent
        self.id = id
        self.child = None

    def create(self):
        id = self.stackscount + 1
        id = str(id) + "_stack"
        return Stack(self, id)

    def push(self, item):
        if self.size() <= self.capacity:
            self.items.append(item)
        else:
            if self.child is None:
                self.child = self.create()
            self.child.push(item)

    def pop(self):
        if self.child is not None:
            item = self.child.pop()
            if len(self.child.items) == 0:
                self.child = None
        else:
            item = self.items.pop()
        return item

    def popAt(self):
        pass

    def peek(self):
        if self.child is not None:
            item = self.child.peek()
        else:
            item = self.items[len(self.items)-1]
        return item

    def size(self):
        l = len(self.items)
        if self.child is not None:
            l += self.child.size()
        return l

s = Stack()
s.push(10)

popAt仍然有待实现,但我对其进行了测试,它在推入和清空时正确创建了新堆栈,并在弹出时将其删除。

popAt的实现将需要对当前的pop实现进行一些改进,以允许删除中间堆栈:

def pop(self):
    if self.child is not None:
        item = self.child.pop()
        if len(self.child.items) == 0:
            self.child = self.child.child
            if self.child is not None:
                self.child.parent = self
    else:
        item = self.items.pop()
    return item

def popAt(self, stacknumber):
    s = self
    for i in range(stacknumber):
        s = s.child
        if s is None:
            return None
    if len(s.items) == 0:
        return None
    item = s.items.pop()
    if len(s.items) == 0 and s.parent is not None:
        s.parent.child = s.child
        if s.child is not None:
            s.child.parent = s.parent
    return item

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM