Необходимо обнаружить оба случая, например, с помощью типа первого аргумента, и соответственно возвратить любого обертка (при использовании без параметра) или декоратор (при использовании с аргументами).
from functools import wraps
import inspect
def redirect_output(fn_or_output):
def decorator(fn):
@wraps(fn)
def wrapper(*args, **args):
# Redirect output
try:
return fn(*args, **args)
finally:
# Restore output
return wrapper
if inspect.isfunction(fn_or_output):
# Called with no parameter
return decorator(fn_or_output)
else:
# Called with a parameter
return decorator
При использовании @redirect_output("output.log")
синтаксис, redirect_output
называют с отдельным аргументом "output.log"
, и он должен возвратить декоратора, принимающего, что функция украшена как аргумент. При использовании в качестве @redirect_output
это называют непосредственно с функцией, которая будет украшена как аргумент.
Или другими словами: @
синтаксис должен сопровождаться выражением, результатом которого является функция, принимающая, что функция украшена как собственный аргумент, и возвращающий украшенную функцию. Само выражение может быть вызовом функции, который имеет место с @redirect_output("output.log")
. Замысловатый, но истинный:-)
Ладно, это действительно заставило меня решить проблему, и я пощаду других.
Проблема заключалась в том, что я использовал <% @ ServiceHost Factory = "System.ServiceModel.Activation.WebServiceHostFactory" Service = "fullQualifiedClassName"%>
, который представляет собой красивый и простой подход к заводской реализации.
Однако у этого подхода есть свои недостатки; поскольку конфигурация файла web.config не требуется, класс WebServiceHostFactory по своей задумке никогда не читает из файла web.config. Я знаю; Я мог унаследовать от этого класса и внести соответствующие изменения, чтобы он действительно мог читать из файла конфигурации, но это казалось немного выходящим за рамки.
Мое решение состояло в том, чтобы вернуться к более традиционному способу реализации WCF; <% @ ServiceHost Service = "fullQualifiedClassName" CodeBehind = "~ / App_Code / Catalogue.cs"%>
, а затем использовать мои уже настроенные значения в файле web.config.
Вот мои измененные файл web.config (относительно головной боли Мэддокса):
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="XmlMessageBinding" maxReceivedMessageSize="5000000" maxBufferPoolSize="5000000" maxBufferSize="5000000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
<readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" />
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="fullyQualifiedClassName" behaviorConfiguration="DevelopmentBehavior">
<endpoint name="REST" address="" binding="webHttpBinding" contract="fullyQualifiedInterfaceName" behaviorConfiguration="RestEndpointBehavior" bindingConfiguration="XmlMessageBinding" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DevelopmentBehavior">
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
<behavior name="ProductionBehavior">
<serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="false"/>
<serviceMetadata httpGetEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Еще одно преимущество этого изменения заключается в том, что теперь вы можете ссылаться на службу WCF-rest непосредственно из .NET; это невозможно сделать с использованием модели Factory и моей реализации XmlElement во всем решении.
Я надеюсь, что это может помочь другим в решении подобных проблем ...
Это запись в блоге, которую я написал, которая воспроизводит эту проблему с абсолютно минимальным сервером WCF и частью клиента:
WCF - Исправление исключений длины строки на стороне клиента
В частности, вы можете нужна настраиваемая конфигурация привязки. По крайней мере, воспроизведение этого примера может дать вам некоторые идеи для вашей конкретной ситуации.