I'm trying to understand OOP in Python and I have this "non-pythonic way of thinking" issue. I want a method for my class that verifies the type of the argument and raises an exception if it isn't of the proper type (e.g. ValueError). The closest to my desires that I got is this:
class Tee(object):
def __init__(self):
self.x = 0
def copy(self, Q : '__main__.Tee'):
self.x = Q.x
def __str__(self):
return str(self.x)
a = Tee()
b = Tee()
print(type(a)) # <class '__main__.Tee'>
print(isinstance(a, Tee)) # True
b.x = 255
a.copy(b)
print(a) # 255
a.copy('abc') # Traceback (most recent call last): [...]
# AttributeError: 'str' object has no attribute 'x'
So, even that I tried to ensure the type of the argument Q in my copy method to be of the same class, the interpreter just passes through it and raises an AttributeError when it tries to get a x member out of a string.
I understand that I could do something like this:
[...]
def copy(self, Q):
if isinstance(Q, Tee):
self.x = Q.x
else:
raise ValueError("Trying to copy from a non-Tee object")
[...]
a = Tee()
a.copy('abc') # Traceback (most recent call last): [...]
# ValueError: Trying to copy from a non-Tee object
But it sounds like a lot of work to implement everywhere around classes, even if I make a dedicated function, method or decorator. So, my question is: is there a more "pythonic" approach to this?
I'm using Python 3.6.5, by the way.
copywould be better written as a class method, as it is an alternate constructor for your class.@classmethod def copy(cls, q): return Tee(Q.x). This requires a slight generalization of__init__todef __init__(self, x=0): self.x = x.