简体   繁体   English

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

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

I am trying to solve this problem: 我正在尝试解决这个问题:

Imagine a (literal) stack of plates. 想象一下(文字)一叠盘子。 If the stack gets too high, it might topple. 如果堆栈太高,可能会倾倒。 There- fore, in real life, we would likely start a new stack when the previous stack exceeds some threshold. 因此,在现实生活中,当前一个堆栈超过某个阈值时,我们可能会启动一个新的堆栈。 Implement a data structure SetOfStacks that mimics this. 实现一个模仿它的数据结构SetOfStacks。 SetOf- Stacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity. SetOf-Stacks应该由几个堆栈组成,并且一旦前一个堆栈超过容量,就应该创建一个新的堆栈。 SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack (that is, pop() should return the same values as it would if there were just a single stack). SetOfStacks.push()和SetOfStacks.pop()的行为应与单个堆栈相同(也就是说,pop()返回的值应与仅有单个堆栈时的值相同)。 Bonus: Implement a function popAt(int index) which performs a pop operation on a specific sub-stack. 奖励:实现一个函数popAt(int index),该函数在特定的子堆栈上执行弹出操作。

So I wrote the code: 所以我写了代码:

#!/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)

How do I create a new s type object dynamically at runtime? 如何在运行时动态创建新的s类型对象? I searched on the internet and found that using new.instance or new.classobj is the solution but when I did so my new object did not seem to have items from __init__ function. 我在互联网上搜索,发现使用new.instance或new.classobj是解决方案,但是当我这样做时,我的新对象似乎没有__init__函数中的items In python3, type() seems to be the answer but the docs doesn't have any examples. 在python3中, type()似乎是答案,但是该文档没有任何示例。

You've confused yourself by referring to a "type object". 您通过引用“类型对象”感到困惑。 In Python that means the class itself, not its instances. 在Python中,这意味着类本身,而不是其实例。

To create new Stack objects, simply do what you're already doing: call the Stack class. 要创建新的Stack对象,只需执行您已经在做的事情:调用Stack类。 You can append them to a list: 您可以将它们附加到列表中:

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

However, as jon points out, that won't solve your problem since you haven't defined the SetOfStacks class. 但是,正如jon所指出的那样,由于您尚未定义SetOfStacks类,因此无法解决您的问题。

The type() function is indeed what you are looking for. type()函数确实是您要寻找的。 Documentation can be found here: https://docs.python.org/2/library/functions.html#type 可以在这里找到文档: https : //docs.python.org/2/library/functions.html#type

You can call it like this: 您可以这样称呼它:

# 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()

It looks like you are just looking at instance creation though: 看来您只是在查看实例创建:

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()

You could simply use a parent-child relation : when a Stack is full, it creates a child and delegate next pushes to it. 您可以简单地使用父子关系:当堆栈已满时,它将创建一个子级并委托下一次推送。 It could lead to : 它可能导致:

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 is still to be implemented, but I tested it and it correctly creates new stacks when pushing and empties and removes them when popping. popAt仍然有待实现,但我对其进行了测试,它在推入和清空时正确创建了新堆栈,并在弹出时将其删除。

The implementation of popAt will require some evolutions to current pop implementation, to allow removing an intermediate stack : 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