在IronPython中使用.NET值类型时有一个众所周知的问题.最近,当我尝试在C#中使用Python作为嵌入式脚本语言时,这让我很头疼.问题可归纳如下:
给定一个C#结构,例如:
struct Vector {
public float x;
public float y;
}
Run Code Online (Sandbox Code Playgroud)
还有一个C#类如:
class Object {
public Vector position;
}
Run Code Online (Sandbox Code Playgroud)
IronPython中将发生以下情况:
obj = Object()
print obj.position.x # prints ‘0’
obj.position.x = 1
print obj.position.x # still prints ‘0’
Run Code Online (Sandbox Code Playgroud)
正如文章所述,这意味着价值类型大多是不可变的.但是,这是一个问题,因为我计划使用如上所示实现的矢量库.是否有任何变通方法可以使用依赖于值类型的现有库?修改库将是最后的手段,但我宁愿避免这种情况.
假设我有以下代码:
public static class Foo
{
public static void Bar() {}
}
Run Code Online (Sandbox Code Playgroud)
在IronPython中,我想:
Bar()
Run Code Online (Sandbox Code Playgroud)
无需在线上包含Foo.现在,我知道我可以说:
var Bar = Foo.Bar
Bar()
Run Code Online (Sandbox Code Playgroud)
但我想使用SetVariable在我的C#代码中将Bar添加到ScriptScope.我怎样才能做到这一点?
我想基于IronStudio添加自己的项目类型.所以,
Templates\Projects\MyProject文件夹,并向其中添加了一个文件,并将其属性"包含在VSIX中"设置为true.然后修改了要从IronStudio中派生的主Package类PythonProjectPackage,并设置ProvideProjectFactory属性:
[ProvideProjectFactory(
typeof(PythonProjectFactory),
"Django Project",
"Django Project Files (*.myproj);*.myproj",
"myproj", "myproj",
@"Templates\Projects\MyProject",
LanguageVsTemplate="MyProject")]
public sealed class MyPackage : PythonProjectPackage
Run Code Online (Sandbox Code Playgroud)
跑了.但MyProject没有出现在项目模板中.为什么不?
生成的.pkgdef文件如下所示:
[$RootKey$\InstalledProducts\VSPackage3Package]
@="#110"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"PID"="1.0"
"ProductDetails"="#112"
"LogoID"="#400"
[$RootKey$\Packages\{5cd7435c-7461-459f-80bc-c0c79e9d462f}]
@="Microsoft.VSPackage3.VSPackage3Package, VSPackage3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a4f1577d825253f8"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.VSPackage3.VSPackage3Package"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}]
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\Extensions]
"py"=dword:00000020
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a701-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a702-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a703-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\CLSID\{888888fd-3c4a-40da-aefb-5ac10f5e8b30}]
@="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
"ThreadingModel"="Both"
[$RootKey$\Projects\{888888a0-9f3d-457c-b088-3a5042f75d52}]
@="PythonProjectFactory"
"DisplayName"="My Project"
"DisplayProjectFileExtensions"="My Project Files (*.myproj);*.myproj"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"DefaultProjectExtension"="myproj"
"PossibleProjectExtensions"="myproj"
"ProjectTemplatesDir"="$PackageFolder$\Templates\Projects\MyProject"
"Language(VsTemplate)"="MyProject" …Run Code Online (Sandbox Code Playgroud) 我有一个带有重载静态方法的C#类,如下所示:
// Added to the Simple class in Tutorial\Extend\csextend.cs
public static int Foo(IEnumerable<int> values)
{
return 1;
}
public static int Foo(IEnumerable<string> values)
{
return 2;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从IronPython 2.6中调用它们时出错.我正在传递一个包含字符串的python列表.
import clr
clr.AddReferenceToFile("csextend.dll")
import Simple
Simple.Foo(["alpha", "bravo", "charlie"])
Run Code Online (Sandbox Code Playgroud)
TypeError: Multiple targets could match: Foo(IEnumerable[str]), Foo(IEnumerable[ int])
我的第一个问题是为什么这不起作用?似乎重载解决方案应该对此起作用.这是IronPython中的错误吗?什么是最干净的解决方法.我可以重命名例程,这样它们就不会相互重载,但后来我让铁心怪怪改变了C#类的设计.
是否有一种干净的方法可以给python一个线索,即列表完全由一种类型组成,它应该选择一个特定的重载?
与此问题相关
我正在做的例子可以在这里找到.所以我试图在C#脚本中运行IronPython:
蟒蛇:
def hello(name):
print "Hello " + name + "! Welcome to IronPython!"
return
def add(x, y):
print "%i + %i = %i" % (x, y, (x + y))
return
def multiply(x, y):
print "%i * %i = %i" % (x, y, (x * y))
return
Run Code Online (Sandbox Code Playgroud)
C#:
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting.Hosting;
using System;
namespace IntroIronPython
{
class IronPythonMain
{
static void Main(string[] args)
{
// Create a new ScriptRuntime for IronPython
Console.WriteLine("Loading IronPython Runtime...");
ScriptRuntime …Run Code Online (Sandbox Code Playgroud) 我正在编写一个可以使用IronPython编写脚本的C#应用程序.我希望能够从C#代码发出非致命的Python警告(可以使用常规的Python警告捕获系统来处理).
我已经找到了PythonWarnings.warn方法IronPython.Modules,但它需要一个CodeContext,我无法弄清楚如何创建/获取其中之一.
我从网站下载了 IronPython 2.7.5 二进制文件,并且我需要访问 tkinter 和海龟图形。默认情况下,这些不包含在二进制文件中。因为我在学校,所以我所处的环境非常有限。我的所有文件都存储在 Z: 驱动器上,位于学校中每台计算机都可以访问的外部服务器上。因此,我无法访问 C: 驱动器。所以我无法使用 MSI 文件。不过,我可以运行 zip 文件,这就是我在其上安装 Blender 2.79 和 Ironpython 的方式。我的问题是TKINTER!我需要它,但我不知道如何获得它。我什至不知道 Ironpython 从哪里读取模块!之后我需要知道从哪里获取 tkinter。
字面意思是这个问题的反面,是否有一种DateTime从IronPython 获得.Net的简单方法datetime?
显然,人们可以
DateTime构造函数中但那些都是凌乱的.这也不起作用:
pydate = datetime.datetime.now()
csharp = DateTime(pydate) # Crashes, because .Net wants a 'long' for Ticks
Run Code Online (Sandbox Code Playgroud)
有没有一个简单的演员或简短的方法来获得Ticks.Net想要的?
我不知道这是 IronPython 问题、Revit API 程序集问题还是其他问题。任何有关可能导致这种情况的信息/想法表示赞赏。
我知道这可以通过再次重新导入相同的命名空间来解决,但我很想知道为什么会这样。
下面是正在发生的事情的简短示例。图像显示 RevitPythonShell 控制台输出。
import clr
clr.AddReference('RevitAPI') # Contains Imports Autodesk.Revit.DB
from Autodesk.Revit import DB # OK
DB.Element.Name # OK
DB.Element.Name.GetValue() # OK: Method exists. As Expected
Run Code Online (Sandbox Code Playgroud)
from File1 import DB
DB.Element.Name # OK, Property Exists
DB.Element.Name.GetValue() # *** Method DOES NOT Exist, Attribute Error is raised
from Autodesk.Revit import DB # Re-import the same namespace again
DB.Element.Name.GetValue() # OK: Method Exists
Run Code Online (Sandbox Code Playgroud)
我在带有 VS 2015 的 C#.Net 3.5 应用程序上使用 IronPython。我阅读了有关此主题的所有帖子,但仍然出现此错误。我的代码:
static void Main(string[] args)
{
var engine = Python.CreateEngine();
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\myProject\packages\DynamicLanguageRuntime.1.1.2");
searchPaths.Add(@"C:\myProject\packages\IronPython.2.7.7\lib");
searchPaths.Add(@"C:\myProject");
searchPaths.Add(@"C:\myProject\"where myfile.py exists");
engine.SetSearchPaths(searchPaths);
var mainfile = @"C:\myProject\myfile.py";
var scope = engine.CreateScope();
engine.CreateScriptSourceFromFile(mainfile).Execute(scope);
var result = scope.GetVariable("res");
// Console.WriteLine(result);
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
和 myfile.py 以:
import os
import csv
import unirest
.
.
res = "something"
Run Code Online (Sandbox Code Playgroud)
有人知道可能是什么问题吗?谢谢。