#python #python-2.7 #attributes
#python #python-2.7 #атрибуты
Вопрос:
Вероятно, это вопрос для начинающих, но у меня есть вопрос об атрибутах. У меня есть модуль, отвечающий за действия API Google Docs, который содержит функции для извлечения информации. Я хотел бы иметь возможность ссылаться на определенные переменные из этих функций в качестве атрибутов. Вот пример:
Gdocs.py
def getRows():
rows = #action for getting rows
rowsText = #action for converting to text
General.py
import Gdocs
text = Gdocs.getRows.rowstext
Я знаю, что основной эффект передачи переменных может быть достигнут путем простого возврата значений, но я хотел бы ссылаться на них как на атрибуты, если это возможно. Проще говоря, мой вопрос в том, как вы можете создать атрибут функции, на который я могу ссылаться в другом документе .py?
Спасибо и извините, если на него уже был дан ответ, я пытался выполнить поиск, но продолжал работать с очень специфическими проблемами.
Комментарии:
1. Атрибуты чего именно?
2. Вероятно, вам нужен класс, а не просто функция, если у вас есть как атрибуты, так и методы.
3. @Martijn Pieters: я хотел создать атрибут функции, описанной выше
4. @jonrsharpe: Я тоже хотел использовать класс, но запутался в том, как это сделать. Если мои Gdocs. у py есть несколько классов, тогда я могу ссылаться на атрибут, но мне показалось, что это ненормально — создавать класс для каждой функции, которая мне нужна. Может ли кто-нибудь показать мне базовый пример того, как это может работать, чтобы я мог ссылаться на переменную примерно так: text = Gdocs.GetRows.rowstext ?
5. Атрибуты функции — это просто глобальные переменные с пространством имен; однако неясно, какую проблему вы пытаетесь решить здесь.
Ответ №1:
Звучит так, как будто вы хотите вернуть результат, состоящий из нескольких частей. Не используйте для этого атрибуты функции, вместо этого возвращайте новый объект, к которому можно обращаться с помощью атрибутов. Это также сделало бы его потокобезопасным, поскольку атрибуты функции находятся в той же области, что и сам объект функции: как глобальный.
В стандартной библиотеке есть полезная функция фабрики классов только для таких возвращаемых значений, collections.namedtuple()
:
from collections import namedtuple
Point = namedtuple('Point', 'x y')
def calculate_coordinates(foo, bar, baz):
return Point(42, 81)
Возвращаемое значение представляет собой подкласс кортежа, поэтому его можно адресовать как кортеж (с индексацией), его можно распаковать на отдельные значения или использовать атрибуты:
result = calculate_coordinates(spam, ham, eggs)
print result.x, result.y
или
res_x, res_y = calculate_coordinates(spam, ham, eggs)
все работает.
Ответ №2:
Хотя я понимаю, что вы сказали о нежелании иметь класс для каждой функции…
Когда у вас есть класс, вы можете применить декоратор @property к функциям. Это позволяет эффективно создавать функции, которые демонстрируют поведение, но могут вызываться точно так же, как атрибуты. Далее, если вы хотите создать список квадратов на основе входного списка, вы могли бы создать функцию с именем, подобным глаголу, с именем create_list_of_squares() . Но в этом случае, если вы действительно хотите, чтобы API был простым и абстрагировался от механики, лежащей в основе метода, и просто позволял пользователям получать доступ к атрибутам ‘squares’, вы можете использовать декоратор свойств, например, так…
class SquareList(list):
@property
def squares(self):
return [x ** 2 for x in self]
s = SquareList([1, 2, 3, 4])
print s.squares
что даст:
[1, 4, 9, 16]
Ответ №3:
Это немного странно, но вы можете использовать staticmethod
и классы, чтобы получить то, что вы хотите. А именно:
источник: zattr2.py
class getRows(object):
@staticmethod
def rows(arg):
return [arg, arg]
@staticmethod
def rowsText(arg):
return repr(arg)
использование:
>>> import zattr2
>>> zattr2.getRows.rowsText('beer')
"'beer'"
Смотрите: https://docs.python.org/2/library/functions.html#staticmethod