Я возился с созданием объектов. Я не понимаю, почему это вызывает ошибки при возврате его личности?

   >>> class Complex:
    ...     def __init__(self):
    ...         print(f'Complex identity: {id(self)}' )
    ...

>>> a = Complex() * 27
Complex identity: 2660854434064
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'Complex' and 'int'
0
Richard 4 Фев 2022 в 09:56
Что ты пытаешься сделать? Complex — это класс, который не поддерживает умножение, поскольку вы не определили функцию __mul__. Если вам нужен идентификатор объекта * 27, вы должны сделать a = id(Complex()) * 27
 – 
rchome
4 Фев 2022 в 10:18

3 ответа

Лучший ответ

На самом деле это происходит потому, что объекты Python создаются до назначения переменных. Умножение экземпляра Complex приведет к возникновению исключения, а переменная a останется не созданной из-за исключения в правой части. Но в следующем примере показан эффект создания экземпляра Complex и создается переменная com, которая возвращает адрес памяти объекта. Однако переменная a еще не создана. Переменная слева привязывается к объекту после создания объекта справа. Переменные — это просто ярлыки.

>>> com = Complex()
Complex identity: 2660854433008
>>> com
<__main__.Complex object at 0x0000026B874884F0>
>>> a = Complex() * 27
Complex identity: 2660854434064
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'Complex' and 'int'
 >>> dir()
['Complex', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'com']
1
kibromhft 4 Фев 2022 в 10:29

Вы создаете экземпляр класса и пытаетесь умножить экземпляр на число. Вы хотите выполнить перегрузку операций, см. пример ниже, как правильно это сделать с помощью точек (вы можете настроить его в соответствии с тем, что вы хотите сделать с Комплексное число

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return "<Point x:{0},y:{1}>".format(self.x, self.y)

    # implement addition
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    # implement subtraction
    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    # implement in-place addition
    def __iadd__(self, other):
        self.x += other.x
        self.y += other.y
        return self



    # Declare some points
    p1 = Point(10, 20)
    p2 = Point(30, 30)
    print(p1, p2)

    # Add two points
    p3 = p1 + p2
    print(p3)

    # subtract two points
    p4 = p2 - p1
    print(p4)

    # Perform in-place addition
    p1 += p2
    print(p1)
0
Nir Elbaz 4 Фев 2022 в 10:09

В конкретном случае того, что вы сделали, вы не создали соответствующие методы dunder для своего класса:

class Complex:
    def __init__(self, real, imaginary):
        print(f'Complex identity: {id(self)}')
        self.complex = f"{real} + {imaginary}i"
        self.real = real
        self.imaginary = imaginary

    def __mul__(self, input):
        if isinstance(input, int): #Just an example error type
            return f"{self.real*input} + {self.imaginary*input}i"
        else:
            raise Exception("TypeError: Not complex, real or imaginary")

if __name__ == "__main__":
    a = Complex(10,23)
    print(a*10)
0
Dharman 4 Фев 2022 в 10:21