Как вызвать функцию из функции, которая в классе?
Добрый день. Интересует, можно ли сделать следующее? Допустим у меня есть класс Class, в нём функция function1, а в ней — функция function2. Могу ли я при импорте класса вызвать function2 без вызова функции function1? Или эту функцию нужно returnить?
class Class(): def __init__(self): print('Hi!') def function1(self): def function2(): print('Hello!')
Хочу сделать так —
my_class = Class() my_class.function1().function2()
mahalaka ★★
23.03.16 13:31:45 MSK
Нужно возвращать. Зона видимости вложенной функции такая же, как у переменной => снаружи не видна.
lu4nik ★★★
( 23.03.16 13:33:31 MSK )
true_admin ★★★★★
( 23.03.16 13:34:00 MSK )
Понятно, всем спасибо. Закрываю тред.
mahalaka ★★
( 23.03.16 13:35:45 MSK ) автор топика
Хм, как мне получить такой синтаксис, допустим, если у меня несколько функций в функции function1?
my_class.function1().function2()
my_class.function1.function2()
Пока придумал только такое:
class Class(): def __init__(self): print('Hi!') def function1(self): def function2(): print('Hello!') def function3() print('blabla!') return class = Class() whatever = Class.function1() whatever['function2']() whatever['function3']()
mahalaka ★★
( 23.03.16 14:01:37 MSK ) автор топика
Ответ на: комментарий от mahalaka 23.03.16 14:01:37 MSK

Хм, как мне получить такой синтаксис, допустим, если у меня несколько функций в функции function1?
Ну так в function 1 возвращай объект, в котором определены функции 2 и 3.
Vovka-Korovka ★★★★★
( 23.03.16 14:20:54 MSK )
Ответ на: комментарий от mahalaka 23.03.16 14:01:37 MSK

У тебя function1 как-то по-особому генерирует function2 и function3, или нужна только для того чтобы «получить такой синтаксис»? Если второе (пока похоже на то), то тебе function1 вообще не нужна, можешь использовать там объект. Если первое, но синтаксис нужен такой, то пусть function1 возвращает объект вместо словаря. Задача-то этих махинаций какая? Посильнее запутать код?
Psych218 ★★★★★
( 23.03.16 14:27:51 MSK )
Последнее исправление: Psych218 23.03.16 14:29:43 MSK (всего исправлений: 1)
Могу ли я при импорте класса вызвать function2 без вызова функции function1
class Test: def fun1(self): def fun2(): print("Hello") a = Test() fun2_co = a.fun1.__code__.co_consts[1] # .__code__.co_consts is a tuple of fun1 local objects exec(fun2_co) # OR fun2 = lambda: exec(fun2_co) fun2()
anonymous
( 23.03.16 15:16:04 MSK )
Ответ на: комментарий от Psych218 23.03.16 14:27:51 MSK
Нет, мне нужна некая структуризация — есть класс, который используется для общения с одним сервисом, в нём есть функция смены статуса. И я хочу реализовать что-то типа service.change_status.active()
mahalaka ★★
( 23.03.16 15:46:03 MSK ) автор топика
Ответ на: комментарий от anonymous 23.03.16 15:16:04 MSK
mahalaka ★★
( 23.03.16 15:48:28 MSK ) автор топика
Ответ на: комментарий от mahalaka 23.03.16 15:46:03 MSK

И я хочу реализовать что-то типа service.change_status.active()
А почему не service.change_status(«active»), что было бы логичнее? (Вместо строки можно использовать и константу ACTIVE, суть не в этом).
Просто у тебя получается (даже синтактически), что change_status — это не функция, функция — active(). А change_status — некий объект, который этот набор функций хранит. Это (то, что ты хочешь, судя по желаемому синтаксису) делается так. Просто создай ещё один класс StatusChanger с этими функциями в нём. Но это довольно странно выглядит, непривычный вид API. Change по сути не является методом, а имя говорит обратное, а active, слово, которое «интуитивно» воспринимается не как метод, а как состояние, как раз является функцией. Всё наоборот. change_status можно сделать функцией, возвращающей объект с методами active() и остальными, конечно. Но тогда будет не как ты написал, а service.change_status().active()
Всё же гораздо логичнее будет, если change_status у тебя будет как раз функцией, которая в качестве аргументов принимает статусы, то есть service.change_status(active). Такой код гораздо понятнее и привычнее. Вот она функция, и вот она принимает аргумент. Ну статусами могут быть тоже функции, если хочется (ты можешь сделать active функцией) тогда change_status будет выполнять свой какой-то код и вызывать ещё одну функцию, но такой вид смотрится явно логичнее, чем service.change_status.active()
Просто когда кто-то, кто пользуется этим твоим классом, видит имя change_status, он наверняка предположит, что это функция, которая меняет статус. И всё. Не возвращает функцию, а меняет. Она же change_status, а не get_status_change_functions какая-нибудь. Логично предположить, что она выполняет смену статуса и возвращает успешность сего действа, или ничего, или сам статус, но никак не функцию, которая на самом деле меняет статус, но называется словом active, то есть именем статуса. Ты просто делаешь лишнюю сущность там, где она не нужна. По сути просто излишнее запутывание кода, ничего больше.
Psych218 ★★★★★
( 23.03.16 16:05:23 MSK )
Последнее исправление: Psych218 23.03.16 16:11:54 MSK (всего исправлений: 2)
Основы Python — Функции и Объекты
До сих пор мы видели, как мы можем использовать переменные в Python для хранения различных типов данных, и как мы можем использовать структуры «управления потоком», такие как условия и циклы, чтобы изменить порядок или способ выполнения строк кода. С помощью только этих инструментов мы уже можем начать выражать некоторые довольно сложные логические схемы. Однако, имея только наши текущие инструменты, любой достаточно сложный скрипт начинал бы становиться очень длинным, так как каждый раз, когда мы хотели выполнить определенный процесс, нам приходилось бы переписывать весь его код.
Вот тут-то и появляются функции и классы . Функции позволяют нам инкапсулировать строки кода для создания пользовательских процессов, которые могут быть повторно использованы в любом месте скрипта. Объекты делают эту инкапсуляцию еще одним шагом вперед и заключают в себе не только один процесс, но и несколько связанных процессов, а также локальные переменные, которые могут отслеживать состояние этого объекта.
Функции
Мы уже видели и использовали некоторые функции, такие как type() , str() , .append() , .keys() и range() . Но что такое функции на самом деле?
Как и в математике, функция-это базовая структура, которая может принимать входные данные, выполнять некоторую обработку этих входных данных и возвращать результат. Давайте создадим базовую функцию, которая добавит два к заданному числу и вернет нам результат:
result = inputNumber + 2
Сам по себе этот код будет только определять, что делает функция, но на самом деле не будет выполнять никакого кода. Чтобы выполнить код внутри функции, вы должны вызвать его где-то внутри скрипта и передать ему соответствующие входные данные:
Определение (Definition) функции начинается с ключевого слова def . После этого следует имя функции,которое следует тем же соглашениям об именовании, что и переменные. Внутри круглой скобки после имени функции можно поместить любое количество входных переменных, которые будут переданы функции при ее вызове и доступны в теле функции. При вызове функции можно либо непосредственно передавать значения, либо передавать переменные, внутри которых хранятся значения. Например, этот код вызовет функцию таким же образом:
Здесь значение переменной var , которое в данном случае равно 2 , передается функции addFunction , а затем доступно внутри этой функции через переменную inputNumber . Обратите внимание, что имена двух переменных var и inputNumber не обязательно должны совпадать. Когда значение передается функции, оно образует прямую связь между двумя наборами скобок, которые несут данные.
В этом случае var — это глобальная переменная, которая хранит значение 2 в основном скрипте, в то время как inputNumber — это локальная переменная, которая хранит это значение только на время выполнения этой функции. Таким образом, функции «сворачивают» конкретные задачи и все данные, необходимые для выполнения этой задачи, чтобы ограничить количество глобальных переменных, необходимых в основной функции.
Первая строка, объявляющая функцию и ее входные данные, заканчивается двоеточием , которое должно быть уже знакомо, с остальной частью тела функции, вставленной из первой строки. При необходимости, если вы хотите вернуть значение из функции обратно в основной скрипт, вы можете завершить функцию с помощью ключевого слова return , за которым следует значение или переменная, которую вы хотите вернуть. Как только функция попадет в оператор return , она пропустит остальную часть тела и вернет связанное значение. Это может быть использовано для создания более сложного поведения внутри функции:
return ‘Number must be positive!’
result = inputNumber + 2
Вы можете видеть, что в этом случае, если входные данные меньше нуля, условное условие будет выполнено, что приводит к запуску первого оператора return, пропуская остальную часть кода в функции.
Вы можете передать в функцию любое количество входных данных, но количество входных данных всегда должно совпадать между тем, что определено в функции, и тем, что передается в нее при вызове функции. Например, мы можем расширить нашу простую функцию сложения, чтобы принять два числа, которые будут добавлены:
def addTwoNumbers(inputNumber1, inputNumber2):
result = inputNumber1 + inputNumber2
print addTwoNumbers(2, 3)
Вы также можете вернуть несколько значений, построив их в список, а затем извлекая их из возвращаемого списка. Давайте расширим нашу функцию, чтобы возвращать как сложение, так и умножение двух чисел
def twoNumbers(inputNumber1, inputNumber2):
addition = inputNumber1 + inputNumber2
multiplication = inputNumber1 * inputNumber2
return [addition, multiplication]
result = twoNumbers(2, 3)
print ‘addition: ‘ + str(result[0])
print ‘multiplication: ‘ + str(result[1])
Такие функции чрезвычайно полезны для создания эффективного и читаемого кода. Заключая определенные функциональные возможности в пользовательские модули, они позволяют вам (и, возможно, другим) очень эффективно использовать код, а также заставляют вас быть откровенными о различных наборах операций, происходящих в вашем коде. Вы можете видеть, что основное определение функций довольно просто, однако вы можете быстро начать определять более продвинутые логики, где функции вызывают друг друга и передают входы и возвраты очень сложными способами (вы даже можете передать функцию в качестве входных данных в другую функцию, что мы увидим позже в этих учебниках).
Объекты (Классы)
Шаг за пределы программирования с помощью функций — это объектно-ориентированное программирование или ООП. В ООП программы определяются не как список процедур, которые должны выполняться по очереди, а как набор взаимодействующих объектов. В традиционном процедурном подходе программа выполняется и завершается после выполнения всех процедур. С помощью ООП программа работает непрерывно, а объекты взаимодействуют и запускают различные модели поведения, основанные на событиях, происходящих в реальном времени.
Хотя мы не будем слишком углубляться в ООП в рамках этого курса, мы можем использовать некоторые из его принципов для разработки более сложных проектных пространств. Поэтому важно, по крайней мере, ознакомиться с тем, что такое объекты и как мы можем их использовать в самом базовом смысле. Объект в Python называется классом, но эти два слова часто используются взаимозаменяемо. Вы можете представить себе класс как структуру, которая инкапсулирует набор связанных функций (функции, принадлежащие определенным объектам, часто называются «методами» этого объекта) с набором локальных переменных, которые отслеживают состояние этого класса. Вместе эти переменные и методы определяют «поведение» объекта и определяют, как он взаимодействует с другими объектами в программной «среде».
Давайте подумаем об этом в повседневной жизни. Для животного примером метода может быть «бег». Многие вещи могут работать, поэтому определение работы как функции было бы общим и не обязательно относилось бы к тому, кто выполняет работу. С другой стороны, примером класса может быть «собака», которая будет иметь экземпляр метода «бег», а также другие методы, связанные с тем, чтобы быть собакой, такие как «еда» и «лай». Он также будет иметь набор переменных для хранения информации о данной собаке, такой как ее возраст, порода или вес. Другим классом может быть «человек», который будет хранить различные переменные и будет иметь свою собственную версию методов, таких как «бег» и «еда» (но, надеюсь, не «лай»).
Давайте определим очень простой класс, чтобы увидеть, как он работает. Мы будем использовать пример счетчика, который будет хранить значение и увеличивать это значение на основе запросов пользователей:
def addToCounter(self, inputValue):
Обратите внимание, что мы снова используем сокращение += для увеличения значения переменной count объекта на входное значение. Чтобы использовать этот класс, нам сначала нужно создать его экземпляр, который мы будем хранить в переменной так же, как и любой другой фрагмент данных:
Как только мы создадим экземпляр класса (называемый «instantiation»), мы сможем запустить методы этого экземпляра и запросить его переменные. Обратите внимание, что общее определение класса — это только конструкция. Все переменные внутри класса применяются только к определенному экземпляру, и методы могут выполняться только в том случае, если они связаны с этим экземпляром. Например:
Сразу же вы заметите некоторые различия между тем, как мы определяем функции и классы. Во-первых, никакие переменные не передаются в первой строке определения, так как ключевое слово class определяет только общую структуру класса. После первой строки вы найдете список переменных, которые являются локальными переменными этого класса, и будете отслеживать данные для отдельных экземпляров. После этого у вас будет коллекция локальных методов (помните, что «методы» — это просто функции, принадлежащие определенному классу), которые определяют функциональность класса. Эти методы определяются так же, как и раньше, за исключением того, что вы видите, что первым вводом всегда является ключевое слово self . Это представляет экземпляр объекта и всегда передается как первый входной сигнал в каждый метод в классе. Это позволяет вам запрашивать локальные переменные экземпляра, как вы можете видеть, что мы делаем с переменной count .
Чтобы вызвать метод внутри класса, вы используете имя переменной, хранящей экземпляр, и используете точечную нотацию » . » для вызова метода. Точка — это в основном ваш путь в экземпляр, а также все его данные и функциональность. Мы уже видели эту точку раньше, например, когда вызывали функцию .append() в списке. Это потому, что список на самом деле является классом сам по себе! Когда вы определяете список, вы фактически создаете экземпляр класса list , который наследует все функциональные возможности этого класса (сумасшествие, правда?). На самом деле в Python существует только небольшая коллекция примитивных типов данных (ints, floats, booleans и некоторые другие), а все остальное определяется как классы в рамках ООП. Даже строки — это специальные классы, которые хранят коллекцию символов.
Кстати, можно также использовать синтаксис » . » для запроса локальных переменных экземпляра класса. Например, если мы хотим найти значение переменной count myCounter , мы можем просто задать его, набрав:
Однако это не рекомендуется, поскольку оно раскрывает конечному пользователю истинное имя локальных переменных. В производственной среде это создало бы серьезные риски для безопасности, но считается плохой практикой даже в частном использовании. Вместо этого рекомендуется создать специальные методы accessor для извлечения значений переменных из экземпляра, как это было сделано с помощью метода getCount() в нашем примере. Еще одно преимущество этой практики (которая называется инкапсуляцией) заключается в том, что код легче поддерживать. Вы можете вносить любые изменения в определение класса, включая изменение имен локальных переменных и того, что они делают. Пока вы поддерживаете функции доступа и они возвращают ожидаемый результат, вам не нужно ничего обновлять в основном коде.
Что касается именования классов, то вы можете следовать тому же правилу, что и именование переменных или функций, однако стандартная практика заключается в том, чтобы прописывать каждое слово, включая первое.
Наконец, в приведенном выше примере каждый экземпляр, который мы делаем из CounterClass , будет запускать счетчик в 0 . Однако что делать, если мы хотим указать, каким должно быть это число, когда мы создаем экземпляр класса? Для этого мы можем реализовать метод __init__() (это два подчеркивания на каждой стороне ‘init’):
def __init__(self, inputValue):
def addToCounter(self, inputValue):
Вызов класса как функции
У меня есть класс, который содержит несколько методов, однако открытых методов нет.
Мне нужно чтобы класс вызвался как функция, типа foo(‘some’) и возвращал строку.
Сначала сделал так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#file 1 class foo: def __init__(self, value): self.data(value) __str__(self): return load() #str #. #file 2 from foo import * foo('some')
В этом варианте мне все нравилось, но __str__ не совместим с функциями принимающие строки.
К примеру если вызвать print(foo(‘some’)), то вполне отработает, однако для других функций типа:
open.write(foo('some'))) #вызовет ошибку
Чтобы ошибки не было нужно делать что-то вроде:
open.write(str(foo('some'))))
Затем сделал так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#file 1 class __Foo: def __init__(self, value): self.data(value) def load(self): #. return 'string' #. def foo(value): return __Foo(value).load() #file 2 from foo import * foo('some')
Что в общем-то решило проблему, однако способ какой-то корявый, как мне кажется.
Основной вопрос в том как правильно сделать так чтобы __str__ возвращал полноценную строку или как сделать проще, то о чем я написал в первом абзаце?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Что-то я не понимаю.Вызов метода одного класса из другого класса
Есть два класса первый содержит атрибуты объекта описывающие кнопку: имя, позиция, размер и тд. А.
PyQt5 вызов метода класса из другого класса
Я создаю свой текстовый редактор. Виджет дерева каталогов я отрисовываю с помощью класса: .
Как передать параметры класса в вызов универсальной функции, для конструктора этого класса
Сложно описал, сейчас всё объясню. В ASP.NET, в файле Startup, подключаю модуль. .
Вызов метода класса в лямбде-функции, вызываемой в другом методе этого же класса
Здравствуйте. Помогите грамотно передать в лямбду метод класса. Упрощенно. Есть класс. В одном.
104 / 94 / 14
Регистрация: 20.06.2010
Сообщений: 964
Записей в блоге: 16
Может вот так ?
1 2 3 4 5 6
class foo: def __init__(self, value): self.value = value def __str__(self): return self.value print(foo('some'))
Регистрация: 04.01.2012
Сообщений: 9
Сообщение от bodrich 
Может вот так ?
1 2 3 4 5 6
class foo: def __init__(self, value): self.value = value def __str__(self): return self.value print(foo('some'))
Так я в первом сообщении тоже самое написал. В этом случае другие функции, которые рассчитывают принять строку типа open():
open(foo('some')).write()
Будут ругаться:
1 2 3 4
Traceback (most recent call last): File "foo.py", line 10, in module> file.write(foo('some')) TypeError: must be str, not foo
Поэтому приходится оборачивать в str():
open(str(foo('some'))).write()
Но это коряво, на мой взгляд.
По этой причине я сделал так (сделал класс приватным и отделил его функции):
1 2 3 4 5 6 7 8
class __hidden_class: def __init__(self, value): self.value = value def __str__(self): return self.value def foo(value): return str(__hidden_class(value))
Однако мне кажется, что так никто не делает.
Можно конечно сделать еще так:
1 2 3 4 5 6 7
class foo: def __init__(self, value): self.value = value def get(self): return self.value foo('some').get()
Но так совсем не понятен смысл вызова.
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Вызов функции класса, который наследуется от абстрактного класса
Предположим, что существует класс Base, который является абстрактным class Base< public.
Вызов функции из одного класса кнопкой из другого класса
Доброго времени суток. Помогите разобраться с сигналами и слотами. Уже устал перечитывать не могу.
Вызов функции из модуля в функции класса тестов
Доброго времени суток! Я новичок. У меня закипает мозг и я не могу понять, почему так. у меня.
Вызов функции из класса
как сменить цвет из одного класса в другом классе в главном классе: RelativeLayout rel; rel =.
Вызов функции класса
Здравствуйте, нужно было создать абстрактный класс Figure. На его основе реализовать классы.
Вызов функции класса
Есть некий класс, в котором есть функция. При инициализации класса в MainWindow и последующем.
Вызов метода методом того же класса
Я решил набраться опыта, работая с библиотекой Pillow. Создал программу, которая выводит в консоль среднюю яркость, контрастность, соотношение цветов — в rgb и в виде пропорции, насыщенность, соотношение сторон — в пикселях и в виде пропорции.
После успешного теста проги я решил устроить для себя челендж — написать все методы класса в наименьшее число строк (переносы одной строки не в счет). Пару методов мне удалось написать в виде однострочника, но не хочу создавать строку-монстра, имеющую больше 5 переносов. Для сокращения кода я решил использовать одни методы для работы других.
В качестве примера могу привести метод определения средней контрастности, который требует применение алгоритма из метода средней яркости. Я попробовал пару вариантов вызова метода, но увы пришел к ошибке:
builtins.TypeError: Get_average_brightness() missing 1 required positional argument: ‘self’
Мой код я оставлю ниже, объясните — как вложить метод, если оба метода используют self класса.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
from PIL import Image, ImageDraw def find_median(x): return sum(x) - max(x) - min(x) class Picture(): def __init__(self, image_name): self.image = Image.open(image_name) self.width, self.height = self.image.size self.pix = self.image.load() @staticmethod def Get_average_brightness(self): '''Функция вычисляет среднюю яркость каждого пикселя и вычисляет их среднее арифметическое.''' res = 0 for i in range(self.width): for j in range(self.height): res += sum(self.pix[i, j]) return round(res/(self.width*self.height*3), 1) def Get_average_contrast(self): '''Функция вычисляет среднюю яркость изображения, вычисляет отличие каждого пикселя по яркости и вычисляет их среднее арифметическое.''' brightness = self.Get_average_brightness() for i in range(self.width): for j in range(self.height): deviation = sum(self.pix[i, j])/3 - brightness res += deviation if deviation > 0 else -deviation return round(res/(self.width*self.height), 1)*2 def Get_average_saturation(self): '''Функция вычисляет среднюю насыщенность каждого пикселя и вычисляет их среднее арифметическое.''' return sum([sum([(max(self.pix[i, j]) - min(self.pix[i, j]) + max(self.pix[i, j]) - find_median(self.pix[i, j]))/2 for j in range(self.height)]) for i in range(self.width)])/(self.width*self.height) def Get_average_color(self): '''Функция вычисляет среднее значение RGB для изображения.''' res = [0, 0, 0] for i in range(self.width): for j in range(self.height): for x in range(3): res[x] += self.pix[i, j][x] for i in range(3): res[i] = round(res[i]/(self.width*self.height), 1) return res def Get_average_color_ratio(self): '''Функция выражает среднее значение RGB для изображенияв виде пропорции.''' color = [0, 0, 0] for i in range(self.width): for j in range(self.height): for x in range(3): color[x] += self.pix[i, j][x] for i in range(3): color[i] = round(color[i]/(self.width*self.height), 1) return [round(color[i]/max(color), 1) for i in range(3) if color != [0, 0, 0]] def Get_photo_size(self): '''Функция выводит на экран размер изображения в пикселях''' return [self.width, self.height] def Get_photo_size_ratio(self): '''Функция выражает размер изображения в виде пропорции''' return [round(i/min(self.image.size), 1) for i in (self.width, self.height)] my_image = Picture('C:\\Users\\Pc\\Desktop\\Программирование\\Media\\test.jpg') print('average brightness =', my_image.Get_average_brightness()) print('average contrast =', my_image.Get_average_contrast()) print('average saturation =', my_image.Get_average_saturation()) print('average color =', ', '.join(map(str, my_image.Get_average_color()))) print('average color ratio =', '/'.join(map(str, my_image.Get_average_color_ratio()))) print('image size =', '×'.join(map(str, my_image.Get_photo_size()))) print('image size ratio =', '/'.join(map(str, my_image.Get_photo_size_ratio())))
