@ilitirit:
public class Class<T> where T : IComparable
{
public T Value { get; set; }
public void MyMethod(T val)
{
if (Value == val)
return;
}
}
Оператор '==' не может быть применен к операндам типа 'T' и 'T'
, я не могу думать о способе сделать это без явного пустого теста, сопровождаемого путем вызова метода Equals или объекта. Равняется, как предложено выше.
можно создать решение с помощью Системы. Сравнение, но действительно это собирается закончиться с путем больше строк кода и сложности увеличения существенно.
Это зависит от того, что именно у вас есть как «модуль (предварительно скомпилированный)». Предположим, что это в точности содержимое файла .pyc
, например, ciao.pyc
, созданного:
$ cat>'ciao.py'
def ciao(): return 'Ciao!'
$ python -c'import ciao; print ciao.ciao()'
Ciao!
IOW, таким образом построив ciao.pyc
скажите, что теперь вы это делаете:
$ python
Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> b = open('ciao.pyc', 'rb').read()
>>> len(b)
200
и ваша цель - перейти от этой байтовой строки b
к импортируемому модулю ciao
. Вот как:
>>> import marshal
>>> c = marshal.loads(b[8:])
>>> c
<code object <module> at 0x65188, file "ciao.py", line 1>
вот как вы получаете объект кода из двоичного содержимого .pyc
. Правка : если вам интересно, первые 8 байтов - это «магическое число» и отметка времени - здесь не требуется (если вы не хотите их проверять на работоспособность и вызывать исключения, если это необходимо, но это кажется выходит за рамки вопроса; marshal.loads
все равно поднимется, если обнаружит поврежденную строку).
Затем:
>>> import types
>>> m = types.ModuleType('ciao')
>>> import sys
>>> sys.modules['ciao'] = m
>>> exec c in m.__dict__
то есть: создать новый объект модуля, установить его в sys.modules
, заполнить его, выполнив объект кода в его __ dict __
. Edit : порядок, в котором вы выполняете вставку sys.modules
и exec
, имеет значение тогда и только тогда, когда у вас может быть циклический импорт - но это order import
обычно использует собственный Python, поэтому лучше имитировать его (что не имеет конкретных недостатков).
Вы можете «создать новый объект модуля» несколькими способами (например, из функций в стандартной библиотеке такие модули, как new
и imp
), но «вызов типа для получения экземпляра» - это нормальный способ Python в наши дни, и обычное место для получения типа (если у него нет встроенного имени или он уже у вас уже есть) находится в модуле стандартной библиотеки types
, поэтому я рекомендую именно это.
Теперь , наконец:
>>> import ciao
>>> ciao.ciao()
'Ciao!'
>>>
... вы можете импортировать модуль и использовать его функции, классы и так далее. Другие операторы import
(и из
) затем найдут модуль как sys.modules ['ciao']
, поэтому вам не нужно будет повторять эту последовательность операций (действительно, вам не нужен этот последний import
) здесь, если все, что вам нужно, это убедиться, что модуль доступен для импорта из другого места - я добавляю его только в покажите это работает; -).
Edit : Если вам абсолютно необходимо импортировать таким образом пакеты и модули оттуда, а не "простые модули" как я только что показал, это тоже выполнимо, но немного сложнее. Поскольку этот ответ уже довольно длинный, и я надеюсь, что вы сможете упростить себе жизнь, придерживаясь для этой цели простых модулей, я собираюсь уклониться от этой части ответа; -).
Также обратите внимание, что это может или может не делать то, что вы хотите, в случаях «загрузки одного и того же модуля из памяти несколько раз» (при этом каждый раз модуль перестраивается; вы можете проверить sys.modules и просто пропустить все, если модуль уже существует) и, в частности, когда такое повторяется «загрузка из памяти» происходит из нескольких потоков (требующих блокировок, но лучшая архитектура - иметь один выделенный поток, предназначенный для выполнения задачи, с другими модулями, связывающимися с ним через очередь).
Наконец, есть '
Скомпилированный файл Python состоит из
Чтобы загрузить модуль, вы должны создать объект модуля с помощью imp.new_module ()
, выполнить немашалированный код в пространстве имен нового модуля и поместить его в sys.modules
. Ниже в примере реализации:
import sys, imp, marshal
def load_compiled_from_memory(name, filename, data, ispackage=False):
if data[:4]!=imp.get_magic():
raise ImportError('Bad magic number in %s' % filename)
# Ignore timestamp in data[4:8]
code = marshal.loads(data[8:])
imp.acquire_lock() # Required in threaded applications
try:
mod = imp.new_module(name)
sys.modules[name] = mod # To handle circular and submodule imports
# it should come before exec.
try:
mod.__file__ = filename # Is not so important.
# For package you have to set mod.__path__ here.
# Here I handle simple cases only.
if ispackage:
mod.__path__ = [name.replace('.', '/')]
exec code in mod.__dict__
except:
del sys.modules[name]
raise
finally:
imp.release_lock()
return mod
Обновление : код обновлен для правильной обработки пакетов.
Обратите внимание, что вам необходимо установить ловушку импорта для обработки импорта внутри загруженных модулей. Один из способов сделать это - добавить искатель в sys.meta_path
. См. PEP302 для получения дополнительной информации.