Как я могу вызвать дополнительные внутренние функции в Python 3

1

Я пытаюсь изучить Python, и, создавая свой собственный класс, я столкнулся с этой проблемой. Я хочу вызвать внутреннюю функцию внутри моей функции. Проблема в том, как я могу построить этот тип структуры в Python 3?

    def GetAttributes(self):
        def GetName(self):
            return self.name
        def GetSurname(self):
            return self.surname
        def GetAge(self):
            return self.age
        def GetID(self):
            return self.ID

В основном я хочу иметь возможность сделать это "GetAttributes() GetName()", который вернет self.name или GetAttributes() GetAge(), который вернет себя.

Изменение: для дублирования другого вопроса. Я пытаюсь назвать несколько функций не одним.

  • 6
    Почему вы хотите обернуть эти функции в другую? Не хороший стиль
  • 6
    В Python гораздо предпочтительнее получить прямой доступ к атрибутам, чем предварительно создавать геттеры и сеттеры для каждого. Вы всегда можете превратить простой атрибут в более сложную вещь, используя property позже.
Показать ещё 3 комментария
Теги:
class
python-3.x

3 ответа

0
Лучший ответ

Ответ @ShivamKotwalia - это то, что вы ищете, но, похоже, вы пытаетесь понять, почему ваша реализация не сработала, я немного расширюсь.

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

def GetAttributes(person):
    def GetName(person):
        return person.name
    def GetSurname(person):
        return person.surname
    return GetName, GetSurname

Это позволяет теперь ссылаться на GetName и GetSurname поскольку они были возвращены во внешнюю область. Предполагая, что у вас есть объект Bob, у которого есть name и surname атрибута:

name = GetAttributes(Bob)
name
# (<function GetAttributes.<locals>.GetName at 0x03E9AB28>, <function GetAttributes.<locals>.GetSurname at 0x03E9AB70>)

Обратите внимание, как name имеет две внутренние функции, которые передаются, и что они <locals>. В то время как GetAttributes находится под global областью: <function GetAttributes at 0x03E9AA50>.

Затем вы можете получить две функции по индексу name:

name[0](Bob)
# Bobby
name[1](Bob)
# Tables

Обратите внимание еще раз, как вы по- прежнему требуют Bob быть принят в, потому что обе эти функции были определены как требующие аргумент person. Вы можете удалить аргументы...:

def GetAttributes(person):
    def GetName():
        return person.name
    def GetSurname():
        return person.surname
    return GetName, GetSurname

Но тогда вы все еще сталкиваетесь с несколькими проблемами:

  1. Сначала вам нужно назначить объект для доступа к внутренним функциям.
  2. Функция GetAttributes возвращает ничего, кроме внутренних функций.
  3. Доступ к локальным функциям не имеет значимой структуры.
  4. Там нет гарантии, что объект, который вы передаете, всегда будет иметь атрибуты name и surname.

Именно поэтому существует подход ООП (например, class) и methods:

class Person:
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname
    def GetName(self):
        return self.name
    def GetSurname(self):
        return self.surname

Это касается всех вышеперечисленных вопросов, как у вас сейчас:

  1. Вам просто нужно создать экземпляр class Person вместо беспорядочной обработки функций.
  2. GetAttributes больше не нужен.
  3. Легкий и значимый доступ для получения Person().GetName().
  4. Объекты, использующие эти methods, гарантированно имеют атрибуты name и surname.

"Но как насчет метода GetAttributes?" ты спрашиваешь? Почему у Python есть встроенная getattr() которая будет служить вашим потребностям!

getattr(Bob, 'name')
# Bobby

Сказав все это, существуют function attributes которых вы можете сделать что-то вроде этого:

def GetAttributes(person):
    def GetName():
        return person.name
    def GetSurname():
        return person.surname
    GetAttributes.GetName = GetName
    GetAttributes.GetSurname = GetSurname
    return GetAttributes

GetAttributes(Bob).GetName()
# Bobby

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

  • 0
    Вот что они говорят в дзен: простое лучше, чем сложное. Сложный лучше, чем сложный.
  • 0
    Не видел этого «Таким образом, почему вы решили пройти через эту проблему, когда класс, getattr и методы уже делают все, что вам нужно, с преимуществами установленных гарантий?» во-первых. Я задавал себе эти вопросы: что если у меня слишком много атрибутов? Могу ли я передать их в одной функции, чтобы получить данные организованным способом? Будет ли это более читабельным? Вот почему я спросил, является ли это жизнеспособным
Показать ещё 1 комментарий
1

Я думаю, что ваше решение прост, примените OOP в Python и вместо того, чтобы использовать GetAttributes как функцию, сделать его как класс.

class GetAttributes(object):
    def __init__(self, name, surname, age, custome_id):
        self.name = name
        self.surname = surname
        self.age = age
        self.ID = custome_id
    def GetName(self):
        return self.name
    def GetSurname(self):
        return self.surname
    def GetAge(self):
        return self.age
    def GetID(self):
        return self.ID

Выход

>>> ga = GetAttributes("Shivam", "Kotwalia", 25, "N15T5")
>>> ga.GetName()
    'Shivam'
>>> ga.GetAge()
    25

Я не очень-то уверен, что как вы заполняете данные, но это, похоже, очень питонический способ сделать это :)

Счастливый Pythoning!

  • 0
    Да, я мог бы сделать это, но хотел знать, попробую ли я свою структуру, и это не сработало. Хотел узнать почему. Спасибо за решение
  • 0
    Извините, я не смог повторить вашу идею.
Показать ещё 2 комментария
0

Я думаю, что это может быть немного полезно, попробуйте следующее:

def get_attributes(self, attr_name):
    return {
        'name': self.name,
        'surname': self.surname,
        'age': self.age,
        'ID': self.ID,
    }.get(attr_name)

и вы можете использовать его как get_attributes(name) или get_attributes(age) и так далее. Кроме того, обратите внимание, что в комментариях наши друзья говорят, что имена методов лучше иметь более низкий регистр в Python.it является одним из соглашений об именах Python.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню