Как создать многозначную функцию, которая применяется к классу в Python? - PullRequest
0 голосов
/ 10 июля 2019

Я создал класс и пытаюсь создать функцию, которая, по сути, будет действовать как двоичный оператор между двумя объектами этого класса. Функция, которую я пытался создать, называется «объединить».

Я знаю, что могу создать функцию вне класса, но я хочу, чтобы она была связана с классом.

Справочная информация (на самом деле не обязательно для ответа на вопрос) - класс моделирует математическую группу S4 и представляет собой некоторую практику с объектами и классами для меня. Моя следующая функция состояла в том, чтобы упростить элемент в его простейшее выражение в циклах, что, я уверен, я мог бы сделать, но я предпочел бы сначала отсортировать этот элемент.

Когда я создаю функцию с одним аргументом, она работает нормально - как показано в приведенном ниже коде, с функцией 'cycletype', которая работает, как и ожидалось.

class s4:

    # Define an element of s4, elementlist is a nested list, which is a list of the cycles composing the element.

    def __init__(self, elementlist):
        self.elementlist = elementlist

    # One simple function is to ascertain the cycletype of the element.

    def cycletype(self):
        cycles = []
        for i in self.elementlist:
            cycles.append(len(i))
        return cycles

    # Combining two elements using the group operation is the first function to define.

    def combine(first, second):
        for i in second:
            first.append(i)
        return first

double = s4([[1,2],[3,4]])
triple = s4([[1,2,3]])

print(combine(double,triple))

Я ожидал, что [[1,2], [3,4], [1,2,3]] будет напечатано, однако он показал ошибку NameError, не распознающую объединение.

Ответы [ 4 ]

0 голосов
/ 10 июля 2019

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

class s4:

    # Define an element of s4, elementlist is a nested list, which is a list of the cycles composing the element.
    def __init__(self, elementlist):
        self.elementlist = elementlist

    # One simple function is to ascertain the cycletype of the element.

    def cycletype(self):
        cycles = []
        for i in self.elementlist:
            cycles.append(len(i))
        return cycles

    # Combining two elements using the group operation is the first function to define.

    def combine(self, second):
      #Here I changed first to self, first would be the s4 class that calls the function, in this example double and second would be the one that you want to combine
        first = self.elementlist
        for i in second.elementlist:
            first.append(i)
        return first

double = s4([[1,2],[3,4]])
triple = s4([[1,2,3]])
##As double() is defined within the s4 class, you can only call it from an instance of s4 (in this case you could use doble.combine() or triple.combine())
print(double.combine(triple))

Надеюсь, это поможет.

0 голосов
/ 10 июля 2019

Это потому, что функция объединения не присутствует в глобальной области видимости (я надеюсь, что так она называется, я очень плохо путаю имена).

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

Надеюсь, это помогло

0 голосов
/ 10 июля 2019

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

class S4:

    # Define an element of S4, elementlist is a nested list, which is a list of the cycles composing the element.

    def __init__(self, elementlist):
        self.elementlist = elementlist

    # One simple function is to ascertain the cycletype of the element.

    def cycletype(self):
        cycles = []
        for i in self.elementlist:
            cycles.append(len(i))
        return cycles

    # Combining two elements using the group operation is the first function to define.

    def combine(self, first, second):
        return S4(first.element_list + second.element_list)

Также кажется, что вы можете просто определить __add__ вместо combine,

# Simplified implementation, no error checking
def __add__(self, second):
    return S4(self.element_list + second.element_list)

, позволяющий писать

print(double + triple)

вместо

print(combine(double, triple))
0 голосов
/ 10 июля 2019

Есть две проблемы с кодом

  • , помещая функцию внутрь , класс означает, что это метод.Таким образом, вы должны получить к нему доступ, используя объект s4.combine(s1), а не просто combine(...).В противном случае это будет функция, а не метод.
  • После того, как вы измените это: вы не можете написать for i in second, потому что экземпляры вашего класса не повторяемы.Вы должны реализовать __iter__, чтобы иметь возможность использовать этот синтаксис
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...