-4

为了更清楚我需要什么,这里有一个例子:我有两个盒子,每个盒子有 2 件物品。而且,我希望该项目由它自己的 id 和 box_id 定义。我希望 box_id 是全局的,因为它将在 Box 类的其他方法中使用。

我不想为孩子显式设置父 ID,但我希望它自动继承。

我试过这个:

file>> getid.py

 class Box():
    id = 0
    def __init__(self,id):
        Box.id = id

    def __get__(self):
        return Box.id

    class Item():
        def __init__(self,id):
            self.id = id
            self.box_id = Box.id
        def __get__(self):
            return self.id,Box.id

我在另一个文件中使用它作为:

   from getid import *
   box1 = Box(1)
   box2 = Box(2)       

   In: box1.id
   Out: 2

对于 box1 调用类 Box 并将 id 传递为 1。并在再次为 box2 调用 Box 之前检查,输出box1.id为 1。但在调用 Box 后,输出box1.id更改为 2。

谁能解释一下为什么我在这里得到的输出为 2,但我期望的是 1。

4

2 回答 2

2

项目包含在一个盒子中的事实并不意味着Item 该类需要嵌套在Box 该类中:

这是一个非常简单的结构,可以满足您的要求:

class Box(object):
    def __init__(self, box_id):
        self.box_id = box_id

class Item(object):
    def __init__(self, box, item_id):
        self.box = box
        self.item_id = item_id

box1 = Box(1)

box2 = Box(2)
item1 = Item(box2, 1)
item2 = Item(box2, 2)

(我已经重命名了 ID,所以很清楚哪个是哪个。)

于 2012-12-01T10:27:26.830 回答
2

从你的帖子中理解你想要实现的目标有点困难,但我会试着给你一些我认为你想要做的例子。

让我们从只关注Box-class 开始,暂时忽略Item。这就是你所拥有的:

class Box():
    id = 0
    def __init__(self,id):
        Box.id = id

    def __get__(self):
        return Box.id

方法没用,这里__get__干脆不要用,你不需要。现在我们注意到,你设置Box.id = 0了,这意味着你可以调用print(Box.id)并且它会打印0。你也可以初始化一个新的盒子实例,你可以调用print(box_instance.id),它也会0按预期打印。

但是,在您的__init__方法中,您更改Box.id了 ,而不是实例自己的 id,这是您的意思吗?这是一个关于您的代码会发生什么的快速示例:

In: Box.id
Out: 0

a = Box(1)

In: a.id
Out: 1
In: Box.id
Out: 1

b = Box(2)

In: b.id
Out: 2
In: a.id
Out: 2
In: Box.id
Out: 2

正如您在此处注意到的(或自己测试),在初始化新Box对象时,它会更改Box类的 id,而不是实例的 id。这样,如果您初始化一个新的实例,每个实例的 id 都会发生变化Box。这是因为它实际上不是实例的 id,而是Box.

如果这是您想要的行为,请随意使用它(您仍然不需要__get__),但如果您希望每个 Box 都有其唯一的 id,请使用self而不是 box。

class Box:
    id = 0 # This is Box class' id, it's not even necessary to define it
    def __init__(self, id): # This will be each instance's unique id
        self.id = id #self.id means the instance's unique id

现在我们已经完成了Box大部分工作,我们可以开始研究Item. 我很不确定你想用这个实现什么,但看看你的代码,你似乎实际上是在尝试给每个项目一个唯一的 id(这是一个好主意),然后你想给他们box_id一个简单Box.id的类的ID吗?这对我来说没有任何意义。

我实际上认为您正在尝试实现的目标:将项目插入框中,这样您就希望项目知道它是“父”框的 ID。可以这样做:

class Item: #Notice how inheriting is not needed at all!!
    def __init__(self, id, parent):
        self.id = id
        self.parent = parent
        # I prefer calling it parent, call it what ever you want, box works too

现在我还建议的是:

  1. 在里面Box.__init__(),定义一个列表self.items = []
  2. 在里面Item.__init__(),追加self到父母的项目。self.parent.items.append(self)

这样,您的物品就知道它们所在的盒子,而盒子也知道它们里面有哪些物品。


编辑:关于如何使用父级的简短示例代码:

box1 = Box(1) #box1 has id of 1
box2 = Box(2) #box2 has id of 2
item1 = Item(3, box1) #item1 has id of 3, parent box1
item2 = Item(4, box2) #item2 has id of 4, parent box2
item3 = Item(5, box1) #item3 has id of 5, parent box1

In: item1.id
Out: 3
In: item1.parent.id
Out: 1
In: item2.id
Out: 4
In: item2.parent.id
Out: 2
In: item3.id
Out: 5
In: item3.parent.id
Out: 1
In: item3.parent == item1.parent
Out: True

正如我们在这里看到的,item 可以直接调用它的父方法并使用它的属性。这样,您可以在一个盒子中拥有多个项目,(item1并且item3两者都具有相同的父项)并且每个项目的parent属性都指向该盒子。

基本上你在代码中调用的也是item1.parent == box1如此。item1.parent.iditem.box_id

于 2012-12-01T10:34:35.980 回答