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.