Ошибки реализации метода __eq__ в структуре класса ООП

Вот пара занятий
Родитель

class GeometricShape:
    def __init__(self, name):
        self.set_name(name)

    def get_name(self):
        return self.__name        
    
    def set_name(self,name):
        validate_non_empty_string(name)
        self.__name = name

    def __repr__(self):
        return f'GeometricShape(name = {self.__name})'

    def __eq__(self, other):
        return(self.get_name() == other.get_name() )               

Ребенок

class Rectangle(GeometricShape):
    def __init__(self, length, width, name='Rectangle'):
        #
        # the parent class sets the name in the constructor
        # the name is not set in the child, and we want the naming behavior
        # provided by the parents constructor
        super().__init__(name)
        #
        self.set_length(length)
        self.set_width(width)
    
    def get_length(self):
        return self.__length
        
    def get_width(self):        
        return self.__width
    
    def set_length(self,length):
        # Check the data
        validate_positive_number(length)
        self.__length = length

    def set_width(self,width):
        validate_positive_number(width)        
        self.__width  = width

    def get_perimeter (self):
       return 2 * self.__length + 2 * self.__width    
    
    def get_area (self):
       return self.__length * self.__width    
    
    def __repr__(self):
        return f'Rectangle(a = {self.__length}, b = {self.__width})'     
    
    # Attempted Solution 1
    def __eq__(self, other):
        return( (self.__width == other.get_width() ) and (self.__length == other.get_length() ))
    
    # Attempted Solution 2
    #def __eq__(self, other):
    #    return( (self.__width == other.__width ) and (self.__length == other.__length )) 

Я попробовал два решения для метода eq, оба по-разному терпели неудачу, приводятся соответствующие ошибки, возникающие в каждом из них.

Тесты для запуска == вызываются из зашифрованных файлов Pye.


Вот описание файлов pye:
Что такое файл pye в Python?
py-файлы, содержащие исходный код. Зашифрованные файлы нечитабельны и позволяют защитить авторские права разработчика. Зашифрованным файлам присваивается расширение . py и используются, если нет. py-файл доступен


Решение №1, попытка eq

    def __eq__(self, other):
        return( (self.__width == other.get_width() ) and (self.__length == other.get_length() ))

выдает это сообщение об ошибке: [ОШИБКА] 2024-07-24 GMT-0500 09:38:04.607: Произошла непредвиденная ошибка. Traceback (последний вызов — последний) ... затем длинный путь по зашифрованным файлам, заканчивающийся на:
геометрический_shapes.py", строка 31, в уравнении return(self.get_name() ==other.get_name() )


Решение № 2, попробуйте уравнение:

    def __eq__(self, other):
        return( (self.__width == other.__width ) and (self.__length == other.__length ))             

Выдает это сообщение об ошибке: [ОШИБКА] 2024-07-24 GMT-0500 09:38:04.607: Произошла непредвиденная ошибка. Traceback (последний вызов — последний) ... затем длинный путь по зашифрованным файлам, заканчивающийся на:
геометрический_shapes.py", строка 31, в уравнении return(self.get_name() ==other.get_name() )


Вот мои тесты, которые, похоже, дают ожидаемые результаты:

geometric_shape  = GeometricShape('Triangle')
geometric_shape2 = GeometricShape('Triangle')
geometric_shape3 = GeometricShape('Square')
print(f'shape == shape2:{geometric_shape  == geometric_shape2}')
print(f'shape == shape3: {geometric_shape == geometric_shape3}')
#
rectangle = Rectangle(5, 3)
rectangle2 = Rectangle(5, 3)
rectangle3 = Rectangle(5, 4)
print(f'rectangle == rectangle2: {rectangle == rectangle2}')
print(f'rectangle == rectangle3: {rectangle == rectangle3}')

Какие производят:

shape == shape2:True
shape == shape3: False
rectangle == rectangle2: True
rectangle == rectangle3: False

Полное сообщение об ошибке/отслеживание зашифрованных файлов:

[ERROR] 2024-07-24 GMT-0500 09:38:04.607: An unexpected error has occurred.
Traceback (most recent call last):
File "..submitter_utils\submitter.pye", line 70, in run
  ,$tmf-UR9QO`7m3:/ZUOC`Mr"HEG@322'^F

File ":...submitter_utils\task_handler.pye", line 31, in generate_submission_archive
  ONMZG-M0.d4^.q^W*/O-kA!&&F=,HOemS^G

File "...submitter_utils\task_handler.pye", line 51, in __list_files_for_submission
  )QtuUN&-8jD=?N"m9rd:_#TXTUSTI4'[SAo

File "...submitter_utils\task_handler.pye", line 65, in __generate_task_specific_files
  Hqt-[p'3jY=H$l-q3'VP4?99HU'p@LC(3G!

File "submitter_utils\tasks.pye", line 1040, in task6
  +9i],]UI>>n'i1TAB&tXr;9LBrMeSsA0Yg8

File "...submitter_utils\test_utils.pye", line 329, in test_class
  )JoG=k--Wumo!Ga\[2H8e?[0VI'J;#Vp@Tb

File "..submitter_utils\test_utils.pye", line 164, in test_methods
  M?*>F'c.D4-pmO:TY>Pfa?^A%oB]KD:nJ6B

File "...\ppp-p4-classes-objects\geometric_shapes.py", line 31, in __eq__

  return(self.get_name() == other.get_name() )
AttributeError: 'NoneType' object has no attribute 'get_name'

Тесты, которые не удались, вызываются из зашифрованных файлов.
Мои тесты выше ведут себя так, как ожидалось.
Есть идеи?

Не могу воспроизвести. Укажите код, который вы использовали для тестирования своих классов.

matszwecja 24.07.2024 16:17

Его зашифрованный код

Mikef 24.07.2024 16:17

Что это значит?

deceze 24.07.2024 16:18

Изменение self.get_name' to self.get_name()' привело к появлению другого сообщения об ошибке, сообщение обновилось, чтобы показать изменение кода и новое сообщение об ошибке.

Mikef 24.07.2024 16:23

Было бы полезно, если бы вы предоставили сообщения об ошибках.

oskar 24.07.2024 16:25

Сообщения об ошибках находятся в комментариях, связанных с двумя опробованными мной решениями.

Mikef 24.07.2024 16:27

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

user2357112 24.07.2024 16:30

Где-то в вашем фрагменте кода есть комментарий, который, очевидно, содержит сообщение об ошибке. (1) Это не совсем понятный способ представления сообщения об ошибке. Пожалуйста, включайте сообщение об ошибке в виде обычного текста, а не в комментарий к коду. (2) Это сообщение об ошибке относится к этому коду return( (self.__width == other.get_width() ) and (self.__length == other.get_length() )). Но этого кода нет нигде в представленном вами коде. Убедитесь, что вы предоставляете код и сообщения об ошибках, которые напрямую связаны друг с другом.

trincot 24.07.2024 16:30

Тот факт, что тесты выполняются в вашем коде с использованием зашифрованного кода Python, не должен мешать вам написать собственный тест и воспроизвести проблему. Предоставьте свой код, который вы написали для работы с этими классами и который воспроизводит ошибку.

trincot 24.07.2024 16:35

Идиоматический Python не использует кучу атрибутов с искаженными именами и специальные методы установки и получения. По умолчанию выбраны общедоступные атрибуты, которые при необходимости можно заменить свойствами, которые работают с «частными» (_length) атрибутами.

chepner 24.07.2024 16:41

Эти сообщения об ошибках неполны; они показывают только место возникновения ошибки, а не ее суть.

chepner 24.07.2024 16:42

Сообщения об ошибках относятся к зашифрованным файлам.

Mikef 24.07.2024 16:56

вы задаете много вопросов одновременно. для незашифрованных файлов ваш код работает так, как задумано.

folen gateis 24.07.2024 16:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
13
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не могли бы вы включить полное сообщение об ошибке, возможно, в несколько строк, поскольку в настоящее время оно сообщает только местоположение, но не фактическую ошибку.

Обратите внимание на решение 2: в коде Python не так много ограничений, но я думаю, что это не сработает, это доступ к атрибутам с двойным подчеркиванием извне класса. (Есть способы, но все атрибуты с префиксом __ должны считаться частными и, следовательно, не должны быть доступны извне класса.) Таким образом, self.__width == other.__width выдаст ошибку из-за незнания other.__width, даже если other будет иметь атрибут __width.

Вы можете попробовать запустить окно отладчика, в котором вы поставите точку останова прямо на самой проверке. Обычно используемая защитная техника при реализации методов дандера — это использование метода isinstance, например:

def __eq__(self, other):
    if isinstance(other, Rectangle):
        return(self.__width == other.get_width() and self.__length == other.get_length())
    elif isinstance(other, GeometricShape):
        return super().__eq__(other)
    return False

Это не позволит вам вызывать определенные методы, которые не реализованы в другом объекте.

Could you please include the full error message если вам нужно больше информации, вы не можете написать хороший ответ
folen gateis 24.07.2024 16:53

Другие вопросы по теме