4 ms·
Inline: - Does that work even if the types had fields? Yup! - What about it the fields had a different total size? Totally fine! - What if Baz had no parame
by existencebox 8y ago
Inline:
- Does that work even if the types had fields?
Yup!
- What about it the fields had a different total size?
Totally fine!
- What if Baz had no parameterless constructor (I.e only had a contractor that guaranteed arg > 0 for example)?
Then you throw an exception when you call the constructor.
- Is this like an unsafe pointer cast where “you are responsible, and it will likely blow up spectacularly if you don’t know what you are doing” or is it something safer that will magically work e.g with types of different size?
Mostly the former, but if you're coming from a strongly typed compiled language, it may feel like a bit of the latter too, since if you don't run into any obvious runtime incompatibilities, it'll all "just seem to work" even if the underlying classes are 200% different.
(Disclaimer, I've been using python for ~decade now but am still always nervous to speak authoritatively about it, since I work with peers who are FAR deeper in the actual implementation than I am, and I run the risk of being subtlety incorrect.)
- alkonaut 8y ago> Then you throw an exception when you call the constructor. I was assuming that doing myobj.__class__ = whatever Would not call any constructors?
- existencebox 8y agoYou're correct, sorry, I was not clear. The actual value setting that you cite will work pretty much regardless, you could do __class__ = "Q" for all python cares. The problems would come later when you try to use any functionality of the new __class__ in the manner of the old __class__ for which the new one is not compatible. e.g.: class A: def go(self): print("A ran!") class B: def go(self): print ("B ran!") class C: def go(self, foo): print ("C ran!", foo) a = A() a.__class__ = B a.go() B ran! In [11]: a = A() a.__class__ = C a.go() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-11-b67fe8fb94e1> in <module>() 1 a = A() 2 a.__class__ = C ----> 3 a.go() TypeError: go() missing 1 required positional argument: 'foo'
- alkonaut 8y agoThanks. The constructor thing can be illustrated similarly (found an online compiler, I don't normally python...). class A: i = -1 def __init__(self, num): if num <= 0: raise(Exception('noo!')) def go(self): print('A has value {}'.format(self.i)) class B: def go(self): print ("B ran!") b = B() b.go() b.__class__ = A b.go()