【问题标题】:Two versions of self object within class, how can this be?类中有两个版本的 self 对象,这怎么可能?
【发布时间】:2019-03-21 10:52:02
【问题描述】:

我一直在试验一个包含返回生成类的函数的类。

我希望生成的类具有“自我”对象。它获取 self 中的所有属性,因此我将“self”分配给生成的 self 变量,我将其命名为“own”以减少混淆。

当将 'own' 分配给 'self' 时,python 会创建 own 的第二个版本并为其赋予不同的 id。 调用函数时,返回旧的“自己的”。

import copy
from pprint import pprint


class test_class1(object):
    def __init__(self, number):
        self.number=number
        self.abc=['a','b','c']

    def test_class2(self):
        class test_class(object):
            def __init__(own):
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

                own=copy.deepcopy(self)
                print('own has selfs attributes own.number:',own.number)
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

        return test_class

a=test_class1(7).test_class2()()
print('own has no attributes anymore')
print('own id:')
pprint(id(a))
print('own attributes:')
pprint(a.__dict__)
print('\n')

输出是:

own id:
140178274834248
own attributes:
{}


own has selfs attributes own.number: 7
own id:
140178274834584
own attributes:
{'abc': ['a', 'b', 'c'], 'number': 7}


own has no attributes anymore
own id:
140178274834248
own attributes:
{}

我找到了一种解决方法,但有人可以解释为什么有两个版本的 'own' 具有不同的 ID,以及我如何只能有一个?

【问题讨论】:

  • 您是否只希望实例 a 在实例化后具有与 test_class1(7) 相同的所有属性?
  • 我对您的问题感到非常困惑,但您并没有在第二类中将 own 分配给 self,您只是在命名通常称为 selfown 的内容.变量名self 只是python 中的约定,无论您作为第一个参数传递给__init__ 的任何内容都将是实例变量的名称。你最终得到的是一个id(own),然后是id(copy.deepcopy(self)),其中self来自外部范围,而不是你似乎期望从第二类获得的self
  • test_class2.test_class.__init__() 的开头,own 指向实例 id 140178274834248,它也在全局命名空间中以名称“a”指向。在test_class2.test_class.__init__() 的本地命名空间中,这一行:own=copy.deepcopy(self) 更改了名称own 所指向的内容,但并未修改实例id == 140178274834248
  • 如果您希望a 具有与test_class1(7) 相同的所有属性,您可以在test_class2.test_class.__init__() 中执行类似own.__dict__ = self.__dict__ 的操作
  • @SuperShoot 我希望实例a 具有与test_class2 相同的所有属性。而test_class2 则从test_class1 获取所有属性。

标签: python class self


【解决方案1】:

我认为您需要将own=copy.deepcopy(self) 替换为own.__dict__.update(self.__dict__)。它不会更改id(own),但会将self 的所有属性赋予复制的own 对象。

代码:

import copy
from pprint import pprint


class test_class1(object):
    def __init__(self, number):
        self.number=number
        self.abc=['a','b','c']

    def test_class2(self):
        class test_class(object):
            def __init__(own):
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

                own.__dict__.update(self.__dict__)  # here is the change
                print('own has selfs attributes own.number:',own.number)
                print('own id:')
                pprint(id(own))
                print('own attributes:')
                pprint(own.__dict__)
                print('\n')

        return test_class

a=test_class1(7).test_class2()()
print('own still has attributes')
print('own id:')
pprint(id(a))
print('own attributes:')
pprint(a.__dict__)
print('\n')

输出:

own id:
140228632050376
own attributes:
{}


own has selfs attributes own.number: 7
own id:
140228632050376
own attributes:
{'abc': ['a', 'b', 'c'], 'number': 7}


own still has attributes
own id:
140228632050376
own attributes:
{'abc': ['a', 'b', 'c'], 'number': 7}

【讨论】:

    猜你喜欢
    • 2021-09-16
    • 2012-03-30
    • 2023-03-18
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多