Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
 Аватар для GulgDev
132 / 118 / 29
Регистрация: 09.07.2019
Сообщений: 1,071

Класс FunctionType

12.05.2020, 20:12. Показов 1005. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу объектную систему. Столкнулся с проблемой: не могу написать класс для функции (FunctionType). По идее у неё должен быть метод __call__. Но веть этот метод и есть FunctionType. Я не понимаю, как я могу реализовать FunctionType, если FunctionType состоит из самой себя. Вообщем, очень запутанно.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.05.2020, 20:12
Ответы с готовыми решениями:

Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени?
На самом деле ничё фантастического я не прошу, ведь: template <class T> class matrix { friend class diagonal; ...

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

Как конвертировать класс A в класс B при изменении namespace, если класс не был изменен?
Собсно, это немного сложно объяснить, поэтому приведу пример У меня есть класс Bird в рабочем пространстве nsBird namespace nsBird ...

14
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
12.05.2020, 21:26
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
Но веть этот метод и есть FunctionType.
ась? чавой, милок?

что за класс для функции? растекись мыслью то по форуму
2
Эксперт Python
 Аватар для unfindable_404
693 / 471 / 204
Регистрация: 22.03.2020
Сообщений: 1,051
12.05.2020, 21:42
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
Столкнулся с проблемой: не могу написать класс для функции (FunctionType).
Вы опишите, что вы вообще тут имеете в виду. Ну а мы поможем. А-то пока вообще ничего не понятно.
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
12.05.2020, 23:16
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
Пишу объектную систему
Чой-то?

Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
По идее у неё должен быть метод __call__
Python
1
2
3
4
5
>>> types.FunctionType.__call__
<slot wrapper '__call__' of 'function' objects>
>>> types.FunctionType.__call__(lambda i:i+i, 10)
20
>>>
Ну есть такой.
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
как я могу реализовать FunctionType
Зачем его реализовывать? Вот я выше реализовал функцию через него.
0
 Аватар для GulgDev
132 / 118 / 29
Регистрация: 09.07.2019
Сообщений: 1,071
13.05.2020, 09:31  [ТС]
Цитата Сообщение от unfindable_404 Посмотреть сообщение
Вы опишите, что вы вообще тут имеете в виду. Ну а мы поможем. А-то пока вообще ничего не понятно.
В том и дело, что я и сам ничего не понимаю.
Вот мой код:
Python
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
class MyInstanceOf():
    def __init__(self, MyClass):
        self.Class = MyClass;
        self.Properties = self.Class.GetInstanceProperties();
    def GetProperty(self, PropertyName):
        if PropertyName in self.Properties:
            return self.Properties[PropertyName];
        else:
            pass
class MyObject():
    static_properties = {};
    instance_properties = {};
    def CreateInstance():
        return MyInstanceOf(MyObject);
    def GetStaticProperty(PropertyName):
        if PropertyName in MyObject.static_properties:
            return MyObject.static_properties[PropertyName];
        else:
            pass
    def GetInstanceProperties():
        return MyObject.instance_properties;
    
    def __init_subclass__(cls, static, properties):
        cls.CreateInstance = lambda: MyInstanceOf(cls);
        cls.GetInstanceProperties = lambda: properties;
        cls.GetStaticProperty = lambda PropertyName: static[PropertyName] if PropertyName in static else None;
class FunctionType(MyObject, static={}, properties={}):
    pass
По идее у FunctionType должен быть аналог __call__. То есть я должен добавить в его properties метод call. Но метода call должен быть "функцией" (MyInstanceOf(FunctionType)). Получается рекурсия. но как придти к конечному вызову функции? Например, чтобы я мог распарсить код
Code
1
func()
и вызвать функцию.
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
13.05.2020, 13:19
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
я и сам ничего не понимаю.
это уже поняли. Какую задачу ты решаешь, чего хочешь добиться?

Добавлено через 2 минуты
код ужасен, понятно что ты Pep-8 не читал, но это вот что? какой смысл?
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
cls.GetInstanceProperties = lambda: properties;

точки с запятой? реально?
0
 Аватар для GulgDev
132 / 118 / 29
Регистрация: 09.07.2019
Сообщений: 1,071
13.05.2020, 20:40  [ТС]
Welemir1, я опять пытаюсь написать ЯП. Пишу для него объектную систему, но немогу написать для языка FunctionType.
1
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
15.05.2020, 17:15
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
я опять пытаюсь написать ЯП.
Интерпретатор ЯП?

Синтаксис языка уже есть? А парсер? Пока дерево не построишь - вызывать функции рано.
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
15.05.2020, 18:40
Цитата Сообщение от Рыжий Лис Посмотреть сообщение
А парсер?
Вот такой парсер
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
15.05.2020, 18:51
Н-да, можно считать, что парсера нет. Сначала надо написать токенайзер (1), который будет возвращать токены (грубо говоря, тип токена и значение), потом порисовать синтаксические диаграммы (2), чтобы понимать, что написано в коде (например - вызов функции).

Получим парсер/валидатор кода. А нарастить из этого интерпретатор (3) - легко. Спарсили объявление переменной - сохранили в памяти. Увидели объявление функции - распарсили её, тело функции спраятали в отдельно поддерево. Увидели вызов функции - нашли в дереве - вызвали.

Итого 3 шага.
0
 Аватар для GulgDev
132 / 118 / 29
Регистрация: 09.07.2019
Сообщений: 1,071
16.05.2020, 09:35  [ТС]
Рыжий Лис, я всё это уже сделал, и функции реализовал
0
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
16.05.2020, 11:26
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
я опять пытаюсь написать ЯП. Пишу для него объектную систему, но не могу написать для языка FunctionType.
Я понял бы, если бы Вы писали свой интерпретатор (ЯП) на ассемблере или C#. Но если Вы пишете ЯП на питоне, то внутреннее содержание питона никуда не денется. Поэтому, создавать некоторые свои классы, которые должны подменять классы питона, можно только модифицируя классы питона с помощью подклассов, иначе будет возникать конфликт со встроенными классами питона.
При появлении классов нового стиля "тип" и "класс" стали синонимами.
Python
1
2
3
4
5
6
7
>>> def f(x, y):
    return x + y
 
>>> f(5, 3)
8
>>> type(f)
<class 'function'>
Что значит?
Цитата Сообщение от Hyppoprogramm Посмотреть сообщение
не могу написать для языка FunctionType
В питоне такой тип (класс) уже есть. Если Вы хотите создать свой, отличающийся от встроенного класса, то нужно написать подкласс этого встроенного класса , но с вашими свойствами и методами.
А вообще я не понимаю, зачем Вы этим занимаетесь. Если хотите создать свой ЯП, отличный от питона, скажем ориентированный на какую то узкую область деятельности, то писать нужно на C#. Или же модифицировать питон под какую либо узкую область деятельности способом, которым я описал выше.
Если Вы просто пытаетесь таким образом лучше освоить ООП, то это проще делать решая какую нибудь реально полезную задачу, которая будет полезна Вам в работе или в быту. Я например, для практики в питоне, написал для себя на питоне, используя ООП, телефонный справочник и реально пользуюсь им, что бы быстро находить нужные телефоны.
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
16.05.2020, 11:29
Цитата Сообщение от Viktorrus Посмотреть сообщение
Я понял бы, если бы Вы писали свой интерпретатор (ЯП) на ассемблере или C#.
Ассемблер - это слишком жестоко. Си - вот выбор! Или С#, или ява.

ТС, определённо делает что-то не так. Для начала надо определить структуру узла в дереве разбора, и уже там хранить спарсенные элементы.

Допустим, для простоты у нас есть такой код (на собственном ЯП):

Code
1
2
3
4
function foo() {
   print('hello')
}
foo()
После интерпретации первых трёх строк в глобальной памяти интерпретатора будет лежать идентификатор foo, с типом "функция" и списком входных аргументов (или можно пока реализовать функции без агруметов).

В 4 строке - поиск идентификатора и вызов функции.
0
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
16.05.2020, 11:31
Цитата Сообщение от Viktorrus Посмотреть сообщение
Поэтому, создавать некоторые свои классы, которые должны подменять классы питона, можно только модифицируя классы питона с помощью подклассов
На самом деле можно так же использовать технологию перегрузки операторов, тогда встроенный call будет заменяться методом __call__ из Вашего класса.
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
16.05.2020, 13:03
Кликните здесь для просмотра всего текста
Python
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import string
 
 
class Token:
    __slots__ = 'toknum', 'tokval'
 
    Id = 1
    LeftParen = 2   # (
    RightParen = 3  # )
    LeftBrace = 4   # {
    RightBrace = 5  # }
    ConstString = 6
    KeywordFunction = 7
    KeywordPrint = 8
 
    def __init__(self, toknum, tokval):
        self.toknum = toknum
        self.tokval = tokval
 
    def __str__(self):
        return 'toknum={} tokval="{}"'.format(self.toknum, self.tokval)
 
 
class Tokenizer:
    __slots__ = 's', 'cur', 'linenum', 'rownum'
    
    def __init__(self, s):
        self.s = s
        self.cur = 0
        self.linenum = 1
        self.rownum = 0
 
    def __iter__(self):
        return self
 
    def __next__(self) -> Token:
        if self.cur >= len(self.s):
            raise StopIteration
 
        try:
            while True:
                if self.s[self.cur] in ' \t':
                    self.cur += 1
                    self.rownum += 1
                    continue
                if self.s[self.cur] == '\n':
                    self.cur += 1
                    self.rownum = 0
                    self.linenum += 1
                    continue
                break
        except IndexError:
            raise StopIteration
 
        if self.s[self.cur] == '(':
            self.cur += 1
            self.rownum += 1
            return Token(Token.LeftParen, '(')
 
        if self.s[self.cur] == ')':
            self.cur += 1
            self.rownum += 1
            return Token(Token.RightParen, ')')
 
        if self.s[self.cur] == '{':
            self.cur += 1
            self.rownum += 1
            return Token(Token.LeftBrace, '{')
 
        if self.s[self.cur] == '}':
            self.cur += 1
            self.rownum += 1
            return Token(Token.RightBrace, '}')
 
        # Id
        if self.s[self.cur] in string.ascii_letters:
            v = []
            v.append(self.s[self.cur])
            self.cur += 1
            self.rownum += 1
            while True:
                if self.s[self.cur] not in string.ascii_letters + string.digits:
                    tokval = ''.join(v)
                    toknum = {
                        'function': Token.KeywordFunction,
                        'print': Token.KeywordPrint,
                    }.get(tokval, Token.Id)
                    return Token(toknum, tokval)
                v.append(self.s[self.cur])
                self.cur += 1
                self.rownum += 1
 
        if self.s[self.cur] == "'":
            v = []
            self.cur += 1
            self.rownum += 1
            while True:
                if self.s[self.cur] == "'":
                    self.cur += 1
                    self.rownum += 1
                    return Token(Token.ConstString, ''.join(v))
                v.append(self.s[self.cur])
                self.cur += 1
                self.rownum += 1
 
        self.raise_error('неизвестный символ: "{}"'.format(self.s[self.cur]))
 
    def raise_error(self, msg):
        raise ValueError('{}:{}: {}'.format(self.linenum, self.rownum, msg))
 
 
class Var:
    __slots__ = 'num', 'val'
 
    Func = 1
 
    def __init__(self, num, val):
        self.num = num
        self.val = val
 
 
def main(text):
    globals_var = {}
    
    t = Tokenizer(text)
    while True:
        try:
            token = next(t)
        except StopIteration:
            break
        
        if token.toknum == Token.KeywordFunction:
            name, value = declare_func(t)
            if name in globals_var:
                t.raise_error('id "{}" уже был объявлен раньше'.format(name))
            globals_var[name] = value
            continue
 
        if token.toknum == Token.Id:
            name = token.tokval
 
            # [id]()
            token = next(t)
            if token.toknum != Token.LeftParen:
                t.raise_error('ожидался (, найдено "{}"'.format(token.tokval))
 
            token = next(t)
            if token.toknum != Token.RightParen:
                t.raise_error('ожидался ), найдено "{}"'.format(token.tokval))
 
            if name not in globals_var:
                t.raise_error('функция "{}" не найдена'.format(name))
            call_func(t, globals_var[name].val)
            continue
 
        t.raise_error('ожидалось "function" или id, найдено "{}"'.format(token.tokval))
    print('all ok')
 
 
def declare_func(t):
    # function [id]() { … }
    token = next(t)
    if token.toknum != Token.Id:
        t.raise_error('ожидался id, найдено "{}"'.format(token.tokval))
    func_name = token.tokval
    
    token = next(t)
    if token.toknum != Token.LeftParen:
        t.raise_error('ожидался (, найдено "{}"'.format(token.tokval))
 
    token = next(t)
    if token.toknum != Token.RightParen:
        t.raise_error('ожидался ), найдено "{}"'.format(token.tokval))
 
    token = next(t)
    if token.toknum != Token.LeftBrace:
        t.raise_error('ожидался {, найдено "{}"'.format(token.tokval))
 
    func_body = []
    while True:
        token = next(t)
        if token.toknum == Token.RightBrace:
            return func_name, Var(Var.Func, func_body)
        func_body.append(token)
 
 
def call_func(t, func_body):
    i = 0
    while True:
        try:
            token = func_body[i]
        except IndexError:
            break
        if token.toknum != Token.KeywordPrint:
            t.raise_error('ожидался print, найдено "{}"'.format(token.tokval))
 
        i += 1
        token = func_body[i]
        if token.toknum != Token.ConstString:
            t.raise_error('ожидался constString, найдено "{}"'.format(token.tokval))
        print(token.tokval)
        i += 1
        
 
 
text = '''\
function foo() {
   print 'hello'
}
foo()
foo()
'''
main(text)


Добавлено через 10 минут
Python
1
2
3
4
5
6
            if name not in globals_var:
                t.raise_error('id "{}" не найден'.format(name))
            var = globals_var[name]
            if var.num != Var.Func:
                t.raise_error('"{}" не функция'.format(name))
            call_func(t, var.val)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.05.2020, 13:03
Помогаю со студенческими работами здесь

Наследование (создать класс, который наследует базовый класс и производный класс от базового)
Вот код: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; using namespace std; class...

Класс таблиц баз данных и класс записей в таблице(реляционная таблица). Предусмотреть класс связей между таблицами
Здравствуйте! Никак не могу продумать структуру этой программы. Проходим наследование, но я все равно не знаю, как его здесь применить. Как...

Разработать абстрактный класс класс Point для задания координаты точки на плоскости. Выбирая этот класс в качестве базо
Разработать абстрактный класс класс Point для задания координаты точки на плоскости. Выбирая этот класс в качестве базового разработать...

Класс: Разработать абстрактный класс класс Point для задания координаты...
Всем привет, помогите пожалуйста решить задачу, я уже всю голову сломал, не знаю как решить... Разработать абстрактный класс класс...

Класс: Создать базовый класс Polygon и производный класс Triangle
Создать базовый класс Polygon (многоугольник). Класс должен содержать методы для рисования многоугольника, вычисления периметра, нахождения...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru