草庐IT

c# - 嵌入 IronPython,内置帮助命令,我的 CLR 对象

coder 2024-06-03 原文

我将 IronPython (2.6.1) 嵌入到 C# 程序集中,并将多个对象暴露给使用 PythonEngine.ExecuteFile 执行的脚本。我用

scope.SetVariable("SomeObject", new SomeObject())

engine.Execute("from MyNamespace import SomeObject", scope)

取决于脚本如何使用它们。我的应用程序集被添加到引擎中

engine.Runtime.LoadAssembly(Assembly.GetExecutingAssembly())

现在脚本可以执行 help(SomeObject) 并转储漂亮的小帮助信息 (*),但是它是不完整的。没有对象的事件或属性(当然是公开的)出现,许多“内置”成员也丢失了。

这是奇怪的部分;如果我启动 ipy.exe 并执行以下命令:

import sys
sys.path.append('<location of my app>')
import clr
clr.AddReferenceToFile('myapp.exe')
from MyNamespace import SomeObject
help(SomeObject)

我得到了一个不同的转储,其中包含所有缺失的成员!

为什么两者不同?

奖励问题:假设我让它正常工作,是否可以将我的 CLR 对象的描述性文本添加到 help() 的输出中?就像您可以从脚本中一样,在您的 python 原生类型上?我的第一个猜测是 DescriptionAttribute,但没有用。

(*) 显然,最终的工作脚本不会执行此操作,但它在编写/测试脚本时非常有用。

已回答

这是一个完整的控制台程序,它说明了如何导入用标准 python 库 help() 替换 usless 内部 help() 的站点。

using System;
using System.Collections.Generic;
using System.Reflection;
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting.Hosting.Providers;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Work around issue w/ pydoc - piping to more doesn't work so instead indicate that we're a dumb terminal
            if (Environment.GetEnvironmentVariable("TERM") == null)
                Environment.SetEnvironmentVariable("TERM", "dumb");

            var engine = Python.CreateEngine();

            // Add standard Python library path (is there a better way to do this??)
            PythonContext context = HostingHelpers.GetLanguageContext(engine) as PythonContext;
            ICollection<string> paths = context.GetSearchPaths();
            paths.Add(@"C:\Program Files (x86)\IronPython 2.6\Lib");
            context.SetSearchPaths(paths);

            // Import site module
            engine.ImportModule("site");

            engine.Runtime.LoadAssembly(Assembly.GetEntryAssembly());

            var scope = engine.CreateScope();
            scope.SetVariable("SomeObject", new SomeObject());
            engine.Execute("help(SomeObject)", scope);
        }
    }

    /// <summary>
    /// Description of SomeObject.
    /// </summary>
    public class SomeObject
    {
        /// <summary>
        /// Description of SomeProperty.
        /// </summary>
        public int SomeProperty { get; set; }
        /// <summary>
        /// Description of SomeMethod.
        /// </summary>
        public void SomeMethod() { }
        /// <summary>
        /// Description of SomeEvent.
        /// </summary>
        public event EventHandler SomeEvent;
    }
}

最佳答案

我的猜测是,在您的应用中您没有导入标准库。 IronPython 包括一个内置的帮助功能,标准库包括一个由 site.py 安装的帮助功能。如果您在托管时确保标准库可用,然后在创建引擎时导入 site.py,那么您应该获得标准库帮助。话虽如此,内置帮助未记录事件和属性可能是一个错误或缺少的功能。

关于文档 - 是的,您只需要使用 C# 的文档注释并使用/doc:MyAssemblyName.xml 选项进行构建。如果 XML 文件与程序集位于同一目录中,IronPython 将读取文档字符串并将它们提供给 help() 然后读取的 doc 属性。

关于c# - 嵌入 IronPython,内置帮助命令,我的 CLR 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4635655/

有关c# - 嵌入 IronPython,内置帮助命令,我的 CLR 对象的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  8. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  9. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  10. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

随机推荐