class Foo(float):
...
C = Foo(1.23)
given a class/obj definition like this, is there any way for me to make C read-only? I want it to raise an error if C = ...
is ever called after the object C is initialized.
3 Answers 3
It's not possible. You can make the Foo
object immutable but you can't make variables with references to it immutable. The object doesn't own the variable or have any control over it.
No.
No matter what you assign to C
, C
itself is not an instance of whatever class you create. C
is a variable. Operations that operate on the variable, like C = something_new
, don't even look at your object except to decrement the refcount. You can define how operations on your object behave, but you can't redefine the semantics of the variable itself.
-
So could I make it so that when the refcount is decremented, it produces an error?Owen Mehta-Jones– Owen Mehta-Jones11/04/2019 21:28:00Commented Nov 4, 2019 at 21:28
-
@OwenMehta-Jones you cannot without hacking the interpreter itself.juanpa.arrivillaga– juanpa.arrivillaga11/04/2019 21:32:47Commented Nov 4, 2019 at 21:32
-
@juanpa.arrivillaga That is a big F but imma try anyways.Owen Mehta-Jones– Owen Mehta-Jones11/04/2019 21:33:15Commented Nov 4, 2019 at 21:33
-
1@OwenMehta-Jones: Refcounts go up and down all the time. Even if you could raise an error when your object's refcount goes down, doing so would render your objects completely unusable. It'd be like a doomsday device that goes off whenever someone stops looking at it (or blinks while looking at it).user2357112– user235711211/04/2019 21:35:02Commented Nov 4, 2019 at 21:35
It is not quite what you want to accomplish but I think the following solution is close to your goal. You could consider implementing a singleton. (taken from www.python.org)
class Singleton(object):
def __new__(cls, *args, **kwds):
it = cls.__dict__.get("__it__")
if it is not None:
return it
cls.__it__ = it = object.__new__(cls)
it.init(*args, **kwds)
return it
def init(self, *args, **kwds):
pass
Now you can test with:
>>> class MySingleton(Singleton):
... def init(self):
... print "calling init"
... def __init__(self):
... print "calling __init__"
...
>>> x = MySingleton()
calling init
calling __init__
>>> assert x.__class__ is MySingleton
>>> y = MySingleton()
calling __init__
>>> assert x is y
>>>
You could modify this example to raise an ex or a warning if somebody tries to reassign it. Also if you want your singleton attributes to be immutable you could consider using tuples or namedtuples to accomplish this.
C
? Or do you mean reassigning the nameC
to refer to a different value?