#python #cython
#python #cython
Вопрос:
Я использую cython для компиляции моего скрипта python в модуль .pyd. Мой скрипт на python выглядит так:
class WorkingThread(QtCore.QThread):
...
class Ui_Dialog(object):
...
def Function1():
...
def Function2():
...
def main():
...
Как я могу сделать все классы и функции доступными только внутри скомпилированного модуля?
Поэтому, по сути, я хочу, чтобы модуль pyd «экспортировал» только функцию main(), не более того.
РЕДАКТИРОВАТЬ: парень из cython-users дал мне решение: предварительно объявить класс как
cdef object MyClass
итак, мой код должен выглядеть так
cdef object WorkingThread
cdef object Ui_Dialog
class WorkingThread(QtCore.QThread):
...
class Ui_Dialog(object):
...
cdef Function1():
...
cdef Function2():
...
def main():
...
Комментарии:
1. пожалуйста, опубликуйте данное решение в качестве ответа… вы можете получить несколько голосов и закрыть этот вопрос
Ответ №1:
Честно говоря, для вашего приложения вы, вероятно, не сможете. Способ сделать это — преобразовать ваши функции и классы в функции и классы cdef, а затем вызвать их из вашей основной функции. Но вы не сможете запутать все, если хотите иметь возможность наследования от обычных классов python (таких как QThread). Вот пример, показывающий, что будет открыто, а что нет:
def Function1():
# This function will be exposed
pass
cdef Function2():
# But this cdef function will not
pass
cdef class UI_Dialog:
# This class will be exposed
cdef object storage # This member won't be exposed
def def_func(self):
# This member function will be available
pass
cdef cdef_func(self):
# But this one will not be available
pass
#cdef class WorkingThread(QTCore.QThread):
# This wouldn't even compile; cdef classes can't
# derive from non cdef classes
class WorkingThread(QTCore.QThread):
# This is a normal python class, and is exposed
def __init__(self):
#You're free to call cdef functions in here
Function2()
self.dialog = UI_Dialog()
#But you can't access cdef members,
#So the following wouldn't compile
#self.dialog.storage
#self.dialog.cdef_func()
# But you can access def members
self.dialog.def_func()
cdef hidden_main():
# This function isn't exposed, and you can also call
# cdef functions in here, and access cdef members
Function1()
Function2()
dialog = UI_Dialog()
dialog.def_func()
dialog.cdef_func()
dialog.storage = dict()
workingThread = WorkingThread()
def main():
# Here you can just call your hidden_main
hidden_main()
В принципе, любая логика, которую вы хотите скрыть, должна быть в функциях cdef, вы вообще не можете скрывать классы, но вы можете скрыть доступность членов этих классов. Если вы хотите скрыть член класса, это должен быть класс cdef, а они не могут быть производными от классов Python.
Также важно отметить, что вы не можете просто превратить любую обычную функцию python в функцию cdef (хотя я думаю, что это конечная цель). В настоящее время функции cdef не поддерживают замыкания, и я полагаю, это означает, что они также не поддерживают генераторы.