Python Forum
Inheritance from complex - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Inheritance from complex (/thread-38808.html)



Inheritance from complex - konverner - Nov-27-2022

Hello

I want to create a class "Point" that is a child from Python's complex class.

Here is my code

class Point(complex):
  def __init__(self, **kwargs):
    keys = set(kwargs.keys())
    if {'x','y'} in keys:
      self.z = complex(kwargs['x'], kwargs['y'])
      if {'z'} in keys and self.z != complex(kwargs['z']):
        raise ValueError("'x' and 'y' provided are not consistent with 'z' provided")
    else:
      self.z = complex(kwargs['z'])
      self.x = self.z.real
      self.y = self.z.imag 

    complex.__init__(self, self.x, self.y)

  def distance(self, other) -> float:
    return ((self.real - other.real)**2 + (self.imag - other.imag)**2)**(0.5)

  def __str__(self) -> str:
    return f'({self.real}, {self.imag})'
But it does not work in this case:

p = Point(x=1, y=2)
---
TypeError: 'x' is an invalid keyword argument for complex()
I am confused with it since the example below is similar and it works well:

class Person:
  def __init__(self, fname, lname):
    self.firstname = fname
    self.lastname = lname

class Student(Person):
  def __init__(self, **kwargs):
    self.group = kwargs['group']
    Person.__init__(self, kwargs['name'], kwargs['surname'])

s = Student(name='John', surname='Harris', group='123')
What is the problem of it? It is Python 3.7.15


RE: Inheritance from complex - Gribouillis - Nov-27-2022

Try this code. Use the method __new__ to subclass fundamental builtin types
class Point(complex):
  def __new__(cls, **kwargs):
    z = kwargs.get('z', None)
    if z is None:
      self = complex.__new__(cls, real=kwargs['x'], imag=kwargs['y'])
    else:
      self = complex.__new__(cls, z.real, z.imag)
    return self

  @property
  def x(self):
    return self.real

  @property
  def y(self):
    return self.imag

  def distance(self, other) -> float:
    return abs(self - other)

  def __str__(self) -> str:
    return f'({self.real}, {self.imag})'

p = Point(x=1, y=2)
print(p)
print(p.x)
Output:
(1.0, 2.0) 1.0