Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 42 |
Nodes: | 6 (0 / 6) |
Uptime: | 00:54:37 |
Calls: | 220 |
Calls today: | 1 |
Files: | 824 |
Messages: | 121,521 |
Posted today: | 6 |
[...]
When I try the same with bytes as base class though, that doesn't work
(at least in the Python version I'm using, which is CPython 3.11.2
64-bit on Windows 10):
class MyBytes(bytes):
def __init__(self, data):
super().__init__(data)
print(MyBytes(b'abcdefghijlkmn'))
This results in an exception:
Traceback (most recent call last):
File "test_mybytes.py", line 4, in <module>
print(MyBytes(b'abcdefghijlkmn'))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "test_mybytes.py", line 3, in __init__
super().__init__(data)
TypeError: object.__init__() takes exactly one argument (the instance
to initialize)
I'm passing two arguments (data and the implicit self), and apparently
that's one too many. Let's try without arguments (i.e. only the
implicit self):
class MyBytes(bytes):
def __init__(self, data):
super().__init__()
print(MyBytes(b'abcdefghijlkmn'))
Now it works, and prints b'abcdefghijlkmn'. The same happens with int
as base class, and presumably a number of other classes.
As a follow-up, it looks like this behavior is because bytes and int are >immutable.
Roel Schroeven <roel@roelschroeven.net> wrote:OK.
As a follow-up, it looks like this behavior is because bytes and int are immutable.
Yes.
But that doesn't tell me why using super().__init__(<custom arguments>) doesn't work for immutable classes.
bytes.__init__ does work, but it's just an inherited object.__init__, which does nothing, and takes no parameters.
__init__ cannot change the value of the bytes object; the value is set by bytes.__new__ and cannot change after that.
Best not to define an __init__ method at all, just use __new__.Thanks, that works perfectly. That's also more important than
Something like:
class BytesSubclass(bytes):
def __new__(cls, whatever, arguments, you, like):
bytesvalue = compute(whatever, arguments, you, like)
ob = bytes.__new__(cls, bytesvalue)
ob.some_other_att = compute_something_else(whatever, arguments, you, like)
return ob
It's not entirely clear to me though how bytes.__new__ *can* set an
object's value. Isn't __new__ also a regular function?
On 4/12/24 3:24 am, Roel Schroeven wrote:Aha, yes, that's what I already suspected, but I wasn't sure. Thanks for confirming that.
It's not entirely clear to me though how bytes.__new__ *can* set an
object's value. Isn't __new__ also a regular function?
Yes, but the __new__ methods of the builtin immutable objects (int,
str, bytes, etc.) are implemented in C, and so are able to do things
that Python methods cannot.