当引用成为引用对象时,如何使python对象自身或属性不分配给引用对象?

如何解决当引用成为引用对象时,如何使python对象自身或属性不分配给引用对象?

我希望当一个对象被另一个对象,引用者的自身对象或其属性之一引用时,在引用者对象上不同

这就是我想要做的:

class MyClass:
    .
    .
    .
    .

a = MyClass()
b = a
print(b is a) #must print false
print(b == a) #must print true

#or
a = MyClass()
b = a
print(b.attr is a.attr) #must print false
print(b.attr == a.attr) #must print true

我该如何实现这一目标,通常是在进行a = b之类的任务时,b是对a的引用,希望得到任何帮助,我希望{{1} }是b的副本/深拷贝,与属性相同

从现在开始感谢将要回答问题的人

注意:我正在使用cpython(Python的官方实现)版本Python 3.8

我愿意使用黑魔法

解决方法

您不应该尝试对重载分配做任何事情,因为那不是很pythonic。使用deepcopy函数或复制一个“构造函数”。然后覆盖__eq__函数,以使两个变量测试相等。

,

以您建议的方式重载赋值运算符不是很pythonic。

Python中的赋值运算符旨在引用相同的变量,而不是创建副本。

因此,在某些情况下,例如hash(object.attr)的结果或在该对象上使用pickle模块所产生的结果,此类对象可能无法达到预期的效果。

但是,如果您想要一些黑魔法...


要清楚,我提供这个答案只是为了证明Python确实具有执行此类操作的能力。


一种方法是在访问任何属性时使用__getattribute__()函数创建一个副本。

import copy

class MyClass:
    def __init__(self):
        self.attr = ["foo","bar"]
        
    def __getattribute__(self,name):
        """Access an attribute of this class"""
        attr = object.__getattribute__(self,name)
        return copy.copy(attr)

a = MyClass()
b = a
print(b.attr is a.attr) # prints False
print(b.attr == a.attr) # prints True

有关__getattribute__()的更多信息,请参见:https://docs.python.org/3/reference/datamodel.html


或者,property()仅可用于类上的单个属性。

class MyClass:
def __init__(self):
    self.__attr = ["foo","bar"]

@property
def attr(self):
    """Get the attribute."""
    # Copy could be used instead
    # This works too,if we assume the attribute supports slicing
    return self.__attr[:]

@attr.setter
def attr(self,value):
    """Setting the attribute."""
    # Makes assignment work on this attribute
    # a.attr = []
    # a.attr is a.attr (False)
    self.__attr = value

a = MyClass()
b = a
print(b.attr is a.attr) # prints False
print(b.attr == a.attr) # prints True

这些解决方案适用于大多数对象类型。但这实际上在某些情况下会失败。这是因为某些字符串和一些整数将被标记为具有相同的标识。

例如4 is 2*2,将是True,但是

a = -6
b = -6
print(a is b) # Will print False

这称为“实习”,并在sys模块中简要讨论:https://docs.python.org/3/library/sys.html?highlight=intern#sys.intern

根据Real Python:https://realpython.com/lessons/intern-objects/

在CPython 3.7中,-5和256之间的整数被插入,与 少于20个字符且仅包含ASCII的字符串 字母,数字或下划线。

例如,如果attr = 5attr = 'foo',则上述两种方法都将失败。

a = MyClass()
a.attr = 5
b = a
print(b.attr is a.attr) # prints True
print(b.attr == a.attr) # prints True

可以通过将这些类型包装在子类中来避免这种情况。根据RealPython,仅需修改字符串和一些整数。这种方法的不足之处在于类型比较会失败:

print(type(b.attr) is type(a.attr)) # prints False

因此,如果要包装对象,请确保is操作始终失败,则可以执行以下操作:

import copy
from collections import UserString # Because of course Python has this built in

class UserInt(int): pass

class MyClass:
    def __init__(self,attr = ["foo","bar"]):
        self.attr = attr
        
    def __getattribute__(self,name)

        if isinstance(attr,int) and -5 <= attr <= 256:
            return UserInt(attr) # Prevent a.attr is b.attr if this is an int
        elif isinstance(attr,str):
            return UserString(attr) # Prevent a.attr is b.attr for strings
        #else
        return copy.copy(attr)

a = MyClass()
b = a
print(b.attr is a.attr) # prints False
print(b.attr == a.attr) # prints True

a.attr = 7
b = a
print(b.attr is a.attr) # prints False
print(b.attr == a.attr) # prints True

a.attr = "Hello"
print(b.attr is a.attr) # prints False
print(b.attr == a.attr) # prints True
,

可以用于例如:copy.copy和copy.deepcopy ...

对于python3:

print(MyClass() == MyClass())
print(MyClass() is MyClass())

出局:

False
False
>>> 

和其他萨满法将是类似的...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?