Integration官方文档翻译笔记

作者: 网络编程  发布:2019-12-23

Overriding methods

基类方法能够被用Python方法重写

Base type methods can be overriden by defining a Python method with the same name:

>>> class MyClass(System.ICloneable):
...    def Clone(self):
...        return MyClass()
>>> o = MyClass()
>>> o.Clone() #doctest:  ELLIPSIS
<MyClass object at ...>

测算:上边意思只怕是说,Python语法即使允许你不确实贯彻接口方法,编译上通过,但实在运作的时候会报错,说实例中并不设有这几个主意,所以大家必须要写出切实完结

IronPython does require you to provide implementations of interface methods in the class declaration. The method lookup is done dynamically when the method is accessed. Here we see that AttributeError is raised if the method is not defined:

>>> class MyClass(System.ICloneable): pass
>>> o = MyClass()
>>> o.Clone()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'Clone'

在.Net中有的是类型都有泛型和非泛型版本,举个例子上面这几个事例,用泛型和非泛型版本你将拜望分化品种的对象,使用python的dir方法能够明显看见检索出来的章程属性列表是见仁见智的

Subclassing .NET types

支撑Python类世袭或实现.net的类或接口

Sub-classing of .NET types and interfaces is supported using class. .NET types and interfaces can be used as one of the sub-types in the class construct:

>>> class MyClass(System.Attribute, System.ICloneable, System.IComparable):
...     pass

.Net里不帮忙多种世襲,但Python里援救那样干,但是正如代码,你帮忙世襲七个Python类,而不能够继续几个.Net类,不管世袭几个,此中只可以有二个.Net类

.NET does not support multiple inheritance while Python does. IronPython allows using multiple Python classes as subtypes, and also multiple .NET interfaces, but there can only be one .NET class (other than System.Object) in the set of subtypes:

>>> class MyPythonClass1(object): pass
>>> class MyPythonClass2(object): pass
>>> class MyMixedClass(MyPythonClass1, MyPythonClass2, System.Attribute):
...     pass

和.Net相像,可以使用反射来证美赞臣(Meadjohnson卡塔尔(英语:State of Qatar)个类是或不是是有个别类的子类

Instances of the class do actually inherit from the specified .NET base type. This is important because this means that statically-typed .NET code can access the object using the .NET type. The following snippet uses Reflection to show that the object can be cast to the .NET sub-class:

>>> class MyClass(System.ICloneable):
...     pass
>>> o = MyClass()
>>> import clr
>>> clr.GetClrType(System.ICloneable).IsAssignableFrom(o.GetType())
True

下边又说Python并不曾真正世襲.Net子类,见类型映射表?  瞧着好玄乎

Note that the Python class does not really inherit from the .NET sub-class. See type-mapping.

 

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba.Set(0, "hello") # converts the second argument to True.
>>> ba[0]
True
>>> ba.Set(1, None) # converts the second argument to False.
>>> ba[1]
False

Generic methods are exposed as attributes which can be indexed with type objects. The following code calls System.Activator.CreateInstance<T>

object所以也会有Clone方法,调用ICloneable的虚方法Clone,传入参数string,那么解释器会去string类型里搜索Clone方法

展现怎么样调用泛型方法

>>> from System.Collections import BitArray
>>> ba = BitArray(5) # Creates a bit array of size 5

在此Python和.Net调用静态方法的议程是大器晚成律的

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> isinstance(type(ba), type)
True

Note that the Python type corresponding to a .NET type is a sub-type of type:

IronPython also supports inline initializing of the attributes of the instance. Consider the following two lines:

.NET types behave like builtin types (like list), and are immutable. i.e. you cannot add or delete descriptors from .NET types:

Methods with out parameters

Calling a method with "out" (or in-out) parameters requires explicitly passing in an instance of "clr.Reference", if you want to get the updated value from the method call. Note that COM methods with out parameters are not considered Automation-friendly [11]. JScript does not support out parameters at all. If you do run into a COM component which has out parameters, having to use "clr.Reference" is a reasonable workaround:

>>> import clr
>>> from System import Type, Activator
>>> command_type = Type.GetTypeFromProgID("ADODB.Command")
>>> command = Activator.CreateInstance(command_type)
>>> records_affected = clr.Reference[int]()
>>> command.Execute(records_affected, None, None) #doctest:  SKIP
>>> records_affected.Value
0

Another workaround is to leverage the inteorp assembly by using the unbound class instance method syntax of "outParamAsReturnValue = InteropAssemblyNamespace.IComInterface(comObject)".

[11] Note that the Office APIs in particular do have "VARIANT*" parameters, but these methods do not update the value of the VARIANT. The only reason they were defined with "VARIANT*" parameters was for performance since passing a pointer to a VARIANT is faster than pushing all the 4 DWORDs of the VARIANT onto the stack. So you can just treat such parameters as "in" parameters.

Accessing the type library

The type library has names of constants. You can use clr.AddReferenceToTypeLibrary to load the type library.

在ironPython 中想使用.Net的API必需初始入 CLCRUISER,借用CL奇骏导入.Net的类,最常用的是上边这种导法

__repr__/__str__ on .NET objects

不无Python对象都自带__repr__和__str__方法

All Python user types have __repr__ and __str__:

>>> class MyClass(object):
...     pass
>>> o = MyClass()
>>> o.__repr__() #doctest:  ELLIPSIS
'<MyClass object at ...>'
>>> o.__str__() #doctest:  ELLIPSIS
'IronPython.NewTypes.System.Object_...'
>>> str(o) #doctest:  ELLIPSIS
'<MyClass object at ...>'

For .NET types which do not override ToString, IronPython provides __repr__ and __str__ methods which behave similar to those of Python user types [10]:

想见:不重写.Net对象的 ToString方法的目的,它让你能够把它当成Python对象来管理,即便您想改写Tostring就重写它的__repr__和_-str__主意就好了?

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba.ToString() # BitArray inherts System.Object.ToString()
'System.Collections.BitArray'
>>> ba.__repr__() #doctest:  ELLIPSIS
'<System.Collections.BitArray object at ... [System.Collections.BitArray]>'
>>> ba.__str__() #doctest:  ELLIPSIS
'<System.Collections.BitArray object at ... [System.Collections.BitArray]>'

For .NET types which do override ToString, IronPython includes the result of ToString in __repr__, and maps ToString directly to __str__:

估算:若是ToString得不到您想要的结果,那么结果也许包罗在__repr__和__str__ 方法里头?

>>> e = System.Exception()
>>> e.ToString()
"System.Exception: Exception of type 'System.Exception' was thrown."
>>> e.__repr__() #doctest:  ELLIPSIS
"<System.Exception object at ... [System.Exception: Exception of type 'System.Exception' was thrown.]>"
>>> e.__str__() #doctest:
"System.Exception: Exception of type 'System.Exception' was thrown."

For Python types that override ToString, __str__ is mapped to the ToString override:

对此三个重写了ToString方法的Python对象,调用__str__主意将会直接照射到ToString方法的结果,好乱。。。

>>> class MyClass(object):
...     def ToString(self):
...         return "ToString implemented in Python"
>>> o = MyClass()
>>> o.__repr__() #doctest:  ELLIPSIS
'<MyClass object at ...>'
>>> o.__str__()
'ToString implemented in Python'
>>> str(o) #doctest:  ELLIPSIS
'<MyClass object at ...>'

它又说这看起来有点矛盾,好像在下面这个地址可以得到答案?
There is some inconsistency in handling of __str__ that is tracked by http://ironpython.codeplex.com/WorkItem/View.aspx?WorkItemId=24973

上边这段大致是说在IronPython里不曾像多数高端语言中有 ref和out的定义,在IronPython中对此这种输出援用有二种耍法,后生可畏种隐式的风流浪漫种显式的

>>> ba = BitArray(5, Length = 10)

Invoking .NET instance methods works just like invoking methods on a Python object using the attribute notation:

您习感觉常只好如此玩,须求什么,导入什么

>>> System.Object.ReferenceEquals is System.GC.ReferenceEquals
True
>>> ba.Set(index = 1, value = True)
>>> ba[1]
True

Accessing protected members of base types

想来:上面这段文书档案写的很冲突,第生机勃勃段给了生机勃勃段代码说IronPython中大器晚成经不在子类中向来调用Protected类型的情势会不让访谈,但第二段内容中又建议说实在在python中并从未private protected等等那个概念的存在,並且方法是可以动态增进和删除的,

真的,学过python都知道那么些特点,但文书档案在此之前的有的中有涉及过ironPython中对此来源于.Net的体系是不准动态改进议程和性格的,这两段岂不是冲突了?到底哪类说法才是真的?

可是上边那2段代码自个儿在ipy里敲了试了须臾间,结论正是对此protected类型,确实不可能间接调用,必得定义叁个类世袭今后能力调用。上边文书档案第风流倜傥段中说“除非是三个private绑定”,意思难道是说除非protected不行,假诺是private就足以访谈到了?有机会何人去试一下。

Normally, IronPython does not allow access to protected members (unless you are using private-binding). For example, accessing MemberwiseClone causes a TypeError since it is a protected method:

>>> import clr
>>> import System
>>> o = System.Object()
>>> o.MemberwiseClone()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot access protected member MemberwiseClone without a python subclass of object

IronPython does allow Python sub-types to access protected members of .NET base types. However, Python does not enforce any accessibility rules. Also, methods can be added and removed dynamically from a class. Hence, IronPython does not attempt to guard access to protected members of .NET sub-types. Instead, it always makes the protected members available just like public members:

>>> class MyClass(System.Object):
...     pass
>>> o = MyClass()
>>> o.MemberwiseClone() #doctest:  ELLIPSIS
<MyClass object at ...>

The Python language passes all arguments by-value. There is no syntax to indicate that an argument should be passed by-reference like there is in .NET languages like C# and VB.NET via the ref and out keywords. IronPython supports two ways of passing ref or out arguments to a method, an implicit way and an explicit way.

只是你会发觉唯有静态方法被导进来了,静态属性并不曾被导进来(那和上生机勃勃段看起来有一些水火不容,难精晓。然而写代码的时候自个儿试意气风发试就知道能还是无法行得通了)

猜猜:即便调用五个不设有的重载,IronPython也同意将参数强转后找到最符合匹配的超重载

OleAutomation and COM interop

这段认为对常常干活没什么用,就不去领略了,关于COM对象使用的

IronPython supports accessing OleAutomation objects (COM objects which support dispinterfaces).

IronPython does not support the win32ole library, but Python code using win32ole can run on IronPython with just a few modifications.

Calling from Python

这段看不懂,好像是在说若是叁个.Net的章程被python重写,就不可能用python的措施去调用,那该怎么调才行呢?

When you call a method from Python, and the method overrides a .NET method from a base type, the call is performed as a regular Python call. The arguments do not undergo conversion, and neither are they modified in any way like being wrapped with clr.Reference. Thus, the call may need to be written differently than if the method was overriden by another language. For example, trying to call TryGetValue on the MyDictionary type from the overriding-ref-args section as shown below results in a TypeError, whereas a similar call works with System.Collections.Generic.Dictionary[str, float]:

>>> result, value = d.TryGetValue("yes")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: TryGetValue() takes exactly 3 arguments (2 given)
>>> from System.Guid import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named Guid
>>> s = "hello"
>>> System.Object.GetHashCode(s) == System.String.GetHashCode(s)
True
>>> from System.Runtime.CompilerServices import RuntimeHelpers
>>> RuntimeHelpers.GetHashCode(s) == System.String.GetHashCode(s)
False

Nested types are also imported:

Note that there might exist a non-generic type as well as one or more generic types with the same name [1]. In this case, the name can be used without any indexing to access the non-generic type, and it can be indexed with different number of types to access the generic type with the corresponding number of type parameters. The code below accesses System.EventHandler and also System.EventHandler<TEventArgs>

 

而是IronPython中就像并未有这种限定,只要达成了,就都能够调用。末了大器晚成节估算大约是说,假设达成类中设有同名的秘籍(显式完毕),那么最佳只怕用接口来调用,才精确科学。

>>> del list.append
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: cannot delete attribute 'append' of builtin type 'list'
>>>
>>> import System
>>> del System.DateTime.ToByteArray
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'DateTime'

Overiding events

后生可畏旦要重写.net事件,你得那般干,就像是比重写属性复杂一些,先要重写事件名,然后重写事件对应的add和remove方法

Events have underlying methods which can be obtained using EventInfo.GetAddMethod and EventInfo.GetRemoveMethod

>>> from System.ComponentModel import IComponent
>>> import clr
>>> event_info = clr.GetClrType(IComponent).GetEvent("Disposed")
>>> event_info.GetAddMethod().Name
'add_Disposed'
>>> event_info.GetRemoveMethod().Name
'remove_Disposed'

To override events, you need to define methods with the name of the underlying methods:

>>> class MyComponent(IComponent):
...     def __init__(self):
...         self.dispose_handlers = []
...     def Dispose(self):
...         for handler in self.dispose_handlers:
...             handler(self, EventArgs())
...
...     def add_Disposed(self, value):
...         self.dispose_handlers.append(value)
...     def remove_Disposed(self, value):
...         self.dispose_handlers.remove(value)
...     # Other methods of IComponent not implemented for brevity
>>>
>>> c = MyComponent()
>>> def callback(sender, event_args):
...     print event_args
>>> args = System.Array[object]((System.EventHandler(callback),))
>>> # Use Reflection to simulate a call from another .NET language
>>> event_info.GetAddMethod().Invoke(c, args)
>>>
>>> c.Dispose() #doctest:  ELLIPSIS
<System.EventArgs object at ... [System.EventArgs]>

When the argument type does not exactly match the parameter type expected by the .NET method, IronPython tries to convert the argument. IronPython uses conventional .NET conversion rules like conversion operators , as well as IronPython-specific rules. This snippet shows how arguments are converted when calling theSet(System.Int32, System.Boolean) method:

找不到有关在.Net中什么运用的例证,好奇妙。。。

This allows a unified (Pythonic) view of both Python and .NET types. For example, isinstance works with .NET types as well:

估量:所以object的GetHashCode和String的GetHashCode是如出意气风发辙的,因为string 世袭于object,然则string的GetHashCode方法和RunTimeHelpers类中的GetHashCode差别,估摸,只怕是因为实际完成分裂,解释器能够透过IL代码分辨出达成是不是相通?

If need to get the System.Type instance for the .NET type, you need to use clr.GetClrType. Conversely, you can use clr.GetPythonType to get a type object corresponding to a System.Type object.

这段说的是从.Net那边导进来的类,你不可能自由删除里面的不二法门和性子

ToString on Python objects

假诺对叁个Python对象使用 ToString,尽管信守Python的玩的方法,你重写了__str__主意,你调用ToString解释器还是会去调用.Net里的至极toString方法,并不会调用你定义的那个__str__办法,猜测:约等于说只要一个类是一而再连续自.Net的,那她的规规矩矩正是依据

.Net的来,借使是纯Python的就依照python的准则来?

Calling ToString on Python objects calls the default System.Object.ToString implementation, even if the Python type defines __str__:

>>> class MyClass(object):
...     def __str__(self):
...         return "__str__ result"
>>> o = MyClass()
>>> # Use Reflection to simulate a call from another .NET language
>>> o.GetType().GetMethod("ToString").Invoke(o, None) #doctest:  ELLIPSIS
'IronPython.NewTypes.System.Object_...'

All .NET assemblies have a unique version number which allows using a specific version of a given assembly. The following code will load the version of System.Xml.dll that ships with .NET 2.0 and .NET 3.5:

在IronPython里尽管传入的参数不切合章程要求的参数类型,那么它会结合.Net和Python的汇总法则来举行免强转化,比方上边这一个事例,他会把string转成数字,数字高于1就卓绝bool的true,然后None是Python里的null等同于false

Using the DLR Hosting APIs

想来:大致是说.net能够动用DL兰德酷路泽 Hosting Api来实行ironPython代码

The DLR Hosting APIs allow a .NET application to embed DLR languages like IronPython and IronRuby, load and execute Python and Ruby code, and access objects created by the Python or Ruby code.

 

>>> from System import Environment
>>> Environment
<type 'Environment'>

>>> from System import *
>>> Environment
<type 'Environment'>

在ironPython里你可以用这样的语法来表示.net中的泛型

>>> from System.Collections.Generic import List, Dictionary
>>> int_list = List[int]()
>>> str_float_dict = Dictionary[str, float]()

以下笔记仅记录阅读进度中自己觉着有至关重要记录的源委,大比非常多都以依据翻译软件的机翻,合营个人对代码的敞亮写出的笔记,个别不是很明确的,会在句首标记  估算:

>>> Enumerable.Any(list, lambda x : x < 2)
True

当您导入个别静态属性时,其实你只是导入了七个值类型,假设您用真名称来相比较,你会发觉不大概对等(那句话意思其实有一点点难知晓,反正看代码就知晓大约意思)

Relationship of classes in Python code and normal .NET types

这段看不懂在说吗

A class definition in Python does not map directly to a unique .NET type. This is because the semantics of classes is different between Python and .NET. For example, in Python it is possible to change the base types just by assigning to the __bases__ attribute on the type object. However, the same is not possible with .NET types. Hence, IronPython implements Python classes without mapping them directly to .NET types. IronPython does use some .NET type for the objects, but its members do not match the Python attributes at all. Instead, the Python class is stored in a .NET field called .class, and Python instance attributes are stored in a dictionary that is stored in a .NET field called .dict [7]

>>> import clr
>>> class MyClass(object):
...     pass
>>> o = MyClass()
>>> o.GetType().FullName #doctest:  ELLIPSIS
'IronPython.NewTypes.System.Object_...'
>>> [field.Name for field in o.GetType().GetFields()]
['.class', '.dict', '.slots_and_weakref']
>>> o.GetType().GetField(".class").GetValue(o) == MyClass
True
>>> class MyClass2(MyClass):
...    pass
>>> o2 = MyClass2()
>>> o.GetType() == o2.GetType()
True

Also see Type-system unification (type and System.Type)

[7] These field names are implementation details, and could change.

Extension methods

当下IronPython对于增添方法的帮助还不好,无法像C#那么间接调用,只可以通过静态方法来调用,譬喻,要是string有多少个substring方法是后来扩展的,在c#您能够写成"sadsad".substring(...卡塔尔(قطر‎,然而在IronPython你只好写成System.String.SubString("sadsad"卡塔尔(英语:State of Qatar)

Extension methods are currently not natively supported by IronPython. Hence, they cannot be invoked like instance methods. Instead, they have to be invoked like static methods.

 

上面这段大致是说,在.Net里有索引器的概念,大家得以像下边那样去便利的拜候会集中的有个别对象,

.NET indexers are exposed as __getitem__ and __setitem__. Thus, the Python indexing syntax can be used to index .NET collections (and any type with an indexer):

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba[0]
False
>>> ba[0] = True
>>> ba[0]
True

不过,也支撑使用相比艰苦老土的get和set来走访对象,犹如上面那样

The indexer can be called using the unbound class instance method syntax using __getitem__ and __setitem__. This is useful if the indexer is virtual and is implemented as an explicitly-implemented interface method:

>>> BitArray.__getitem__(ba, 0)
True

上边展示的是显式实现,表明里说只要方法存在种种重载的话,这种方式很好用,举例上面包车型大巴事例,使用CLMurano的秘技生成四个float类型的援用对象,传给方法,然后就和.Net耍法一模二样了,方法还是只回去bool,输出的值将经过援引对象的Value属性来读取,有一点像.Net里的可空类型

>>> from System.Environment import *
>>> Exit is System.Environment.Exit
True

.NET allows a method with a different name to override a base method implementation or interface method slot. This is useful if a type implements two interfaces with methods with the same name. This is known as explicity implemented interface methods. For example, Microsoft.Win32.RegistryKey implementsSystem.IDisposable.Dispose explicitly:

>>> import clr
>>> clr.AddReference("System.Xml")

See appendix-type-conversion-rules for the detailed conversion rules. Note that some Python types are implemented as .NET types and no conversion is required in such cases. See builtin-type-mapping for the mapping.

>>> OSVersion
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'OSVersion' is not defined
>>> System.Environment.OSVersion #doctest:  ELLIPSIS
<System.OperatingSystem object at ...>


下面这段大概是说在IronPython里导入.Net类型,如果用类型对比你会发现,他即可当做.Net类也可以当做Python类
>>> ba = BitArray(5.0)
>>> ba = BitArray(5)
>>> ba.Length = 10

Overriding properties

上面这段大致是说.net里属性都会有意气风发对get set方法,那么些主意是被含有在质量原数据定义里的,假若用python重写.net类的习性,只须要重写get_属性名 就能够兑现对属性重临值的校正,推测:而set方法就如是只读的,不让重写?

.NET properties are backed by a pair of .NET methods for reading and writing the property. The C# compiler automatically names them as get_<PropertyName> and set_<PropertyName>. However, .NET itself does not require any specific naming pattern for these methods, and the names are stored in the the metadata associated with the property definition. The names can be accessed using the GetGetMethod and GetSetMethods of the System.Reflection.PropertyInfo class:

>>> import clr
>>> import System
>>> StringCollection = System.Collections.Generic.ICollection[str]
>>> prop_info = clr.GetClrType(StringCollection).GetProperty("Count")
>>> prop_info.GetGetMethod().Name
'get_Count'
>>> prop_info.GetSetMethod() # None because this is a read-only property
>>>

Overriding a virtual property requires defining a Python method with the same names as the underlying getter or setter .NET method:

>>>
>>> class MyCollection(StringCollection):
...    def get_Count(self):
...        return 100
...    # Other methods of ICollection not overriden for brevity
>>>
>>> c = MyCollection()
>>> # Use Reflection to simulate a call from another .NET language
>>> prop_info.GetGetMethod().Invoke(c, None)
100

If you want to control the exact overload that gets called, you can use the Overloads method on method objects:

__clrtype__

这段看不懂

It is sometimes required to have control over the .NET type generated for the Python class. This is because some .NET APIs expect the user to define a .NET type with certain attributes and members. For example, to define a pinvoke method, the user is required to define a .NET type with a .NET method marked withDllImportAttribute , and where the signature of the .NET method exactly describes the target platform method.

Starting with IronPython 2.6, IronPython supports a low-level hook which allows customization of the .NET type corresponding to a Python class. If the metaclass of a Python class has an attribute called __clrtype__, the attribute is called to generate a .NET type. This allows the user to control the the details of the generated .NET type. However, this is a low-level hook, and the user is expected to build on top of it.

The ClrType sample available in the IronPython website shows how to build on top of the __clrtype__ hook.

 

>>> from System.Collections.Generic import IEnumerable, List
>>> list = List[int]([1, 2, 3])
>>> import clr
>>> clr.AddReference("System.Core")
>>> from System.Linq import Enumerable
>>> Enumerable.Any[int](list, lambda x : x < 2)
True
>> ba = BitArray.__new__(BitArray, 5)


在python里使用.Net类型其实和在.Net中使用方式相似(可以说一模一样)
>>> type(BitArray.Xor)
<type 'method_descriptor'>
>>> type(ba.Xor)
<type 'builtin_function_or_method'>
下面这条我猜他是想说如果按照实例来对比.Net类可以等于Python类,但按照类型来对比,两者并不对等

预计:在IronPython中允许生机勃勃种独特的调用形式,分化.Net,在.net中大家必须要调用子类中完结了接口只怕虚方法的不二等秘书技,但在IronPython中允许直接调用接口中的方法恐怕虚类中的虚方法,解释器能自动找到相称的足够完成,比如上面包车型客车代码,因为string世襲

>>> rkey = Registry.CurrentUser.OpenSubKey("Software")
>>> System.IDisposable.Dispose(rkey)
>>> from Microsoft.Win32 import RegistryKey
>>> clr.GetClrType(RegistryKey).GetMethod("Flush") #doctest:  ELLIPSIS
<System.Reflection.RuntimeMethodInfo object at ... [Void Flush()]>
>>> clr.GetClrType(RegistryKey).GetMethod("Dispose")
>>>
>>> import System
>>> System.Environment
<type 'Environment'>

Delegates

python方法能够被转载为委托,传给事件参数用

Python functions and bound instance methods can be converted to delegates:

>>> from System import EventHandler, EventArgs
>>> def foo(sender, event_args):
...     print event_args
>>> d = EventHandler(foo)
>>> d(None, EventArgs()) #doctest:  ELLIPSIS
<System.EventArgs object at ... [System.EventArgs]>

Some of the conversions supported are:

>>> isinstance(type(ba), type)
True
>>> type(ba) is type
False

Variance

ironPython扶助委托的参数签字和事件必要的嘱托参数签名不相似,比如下例,使用了Python语法里的“Infiniti无名氏参数”

IronPython also allows the signature of the Python function or method to be different (though compatible) with the delegate signature. For example, the Python function can use keyword arguments:

>>> def foo(*args):
...     print args
>>> d = EventHandler(foo)
>>> d(None, EventArgs()) #doctest:  ELLIPSIS
(None, <System.EventArgs object at ... [System.EventArgs]>)

理所必然事件未有再次来到值,可是在这里处也扶助委托可以写重回值(那是Python的语法),但实则运作进度中,重回的值会被忽视

If the return type of the delegate is void, IronPython also allows the Python function to return any type of return value, and just ignores the return value:

>>> def foo(*args):
...     return 100 # this return value will get ignored
>>> d = EventHandler(foo)
>>> d(None, EventArgs())

黄金年代经济委员会托实际重返的归来值类型和事件要求的回来值类型不合乎,那么解释器会尝试强转后再回到

If the return value is different, IronPython will try to convert it:

>>> def foo(str1, str2):
...     return 100.1 # this return value will get converted to an int
>>> d = System.Comparison[str](foo)
>>> d("hello", "there")
100

TODO - Delegates with out/ref parameters

 

.NET types are exposed as Python classes. Like Python classes, you usually cannot import all the attributes of .NET types using from <name> import *:

>>> from System import Activator, Guid
>>> guid = Activator.CreateInstance[Guid]()


下面这段展示了在IronPython中也支持泛型的自动推断功能,比如最后一段

Enumerable.Any[int](list, lambda x : x < 2)
和

Enumerable.Any(list, lambda x : x < 2)
解释器会自动匹配适合的泛型,写的时候就可以省略泛型,另外让我惊奇的是这里头居然也支持lambda,真是屌爆了

Non-default .NET indexers

这段看不懂

Note that a default indexer is just a property (typically called Item) with one argument. It is considered as an indexer if the declaraing type uses DefaultMemberAttribute to declare the property as the default member.

See property-with-parameters for information on non-default indexers.

 

在.Net中二个天性都有风华正茂对Get和Set方法,所以在Python中调用.Net属性举行读写,实际上后台操作也是调用属性的get和set方法来实行

.NET properties are exposed similar to Python attributes. Under the hood, .NET properties are implemented as a pair of methods to get and set the property, and IronPython calls the appropriate method depending on whether you are reading or writing to the properity:

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba.Length # calls "BitArray.get_Length()"
5
>>> ba.Length = 10 # calls "BitArray.set_Length()"

上边的代码约等于上面包车型客车代码,效果等同

To call the get or set method using the unbound class instance method syntax, IronPython exposes methods called GetValue and SetValue on the property descriptor. The code above is equivalent to the following:

>>> ba = BitArray(5)
>>> BitArray.Length.GetValue(ba)
5
>>> BitArray.Length.SetValue(ba, 10)

上边这段大致是说在IronPython里索引.Net类型中的群集数组的措施以至走访属性的艺术,直接待上访谈属性,调用get/set, 调用 对象.Item[?]的方法访谈对象

.NET properties are exposed similar to Python attributes. Under the hood, .NET properties are implemented as a pair of methods to get and set the property, and IronPython calls the appropriate method depending on whether you are reading or writing to the properity:

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba.Length # calls "BitArray.get_Length()"
5
>>> ba.Length = 10 # calls "BitArray.set_Length()"

To call the get or set method using the unbound class instance method syntax, IronPython exposes methods called GetValue and SetValue on the property descriptor. The code above is equivalent to the following:

>>> ba = BitArray(5)
>>> BitArray.Length.GetValue(ba)
5
>>> BitArray.Length.SetValue(ba, 10)

Methods with multiple overloads

想见:上面大约是说在Python里不援救像.Net那样的章程重载,要是您写了叁个Python类世襲.Net类型,想要实现格局重载,那么只好定义一个同方法名,可是参数列表扶持广大个参数的情势来变相的定义出方法重载的功用,比方下边那个例子

*args在Python 语法中象征兵接兵收率性个不限类型的参数

Python does not support method overloading. A class can have only one method with a given name. As a result, you cannot override specific method overloads of a .NET sub-type. Instead, you need to use define the function accepting an arbitrary argument list (see _tut-arbitraryargs), and then determine the method overload that was invoked by inspecting the types of the arguments:

>>> import clr
>>> import System
>>> StringComparer = System.Collections.Generic.IEqualityComparer[str]
>>>
>>> class MyComparer(StringComparer):
...     def GetHashCode(self, *args):
...          if len(args) == 0:
...              # Object.GetHashCode() called
...              return 100
...
...          if len(args) == 1 and type(args[0]) == str:
...              # StringComparer.GetHashCode() called
...              return 200
...
...          assert("Should never get here")
...
>>> comparer = MyComparer()
>>> getHashCode1 = clr.GetClrType(System.Object).GetMethod("GetHashCode")
>>> args = System.Array[object](["another string"])
>>> getHashCode2 = clr.GetClrType(StringComparer).GetMethod("GetHashCode")
>>>
>>> # Use Reflection to simulate a call to the different overloads
>>> # from another .NET language
>>> getHashCode1.Invoke(comparer, None)
100
>>> getHashCode2.Invoke(comparer, args)
200

Note

Determining the exact overload that was invoked may not be possible, for example, if None is passed in as an argument.

 

Accessing Python code from other .NET code

测度:这段大致是说ironPython中的代码首如果由ipy动态疏解的,可是要是要从.net中运作ironpython代码有别的方法

Statically-typed languages like C# and VB.Net can be compiled into an assembly that can then be used by other .NET code. However, IronPython code is executed dynamically using ipy.exe. If you want to run Python code from other .NET code, there are a number of ways of doing it.

 

Invoking static .NET methods is similar to invoking Python static methods:

You can also call the __new__ method to create an instance:

IronPython also supports dict arguments:

Some .NET types only have static methods, and are comparable to namespaces. C# refers to them as static classes , and requires such classes to have only static methods. IronPython allows you to import all the static methods of such static classes. System.Environment is an example of a static class:

微微.net类只含有静态方法,你能够像这么导入

Generic methods

当你用Python重写叁个.Net中的泛型方法时原来泛型<>括号里的品类,在ironPython中将被当成是意气风发组项目参数来对待,仿佛上边这些例子T1,T2被写成参数放在convert方法的参数列表里的,后边调用的时候,用clr的法子传入类型参数生成了贰个

泛型方法,那几个文书档案通篇大量选拔clr的反射方法来调用.net,作者不知晓是还是不是必需这么做技巧调用,如若是的话,那可真是太难为了, 并且品质相对不咋地

When you override a generic method, the type parameters get passed in as arguments. Consider the following generic method declaration:

// csc /t:library /out:convert.dll convert.cs
public interface IMyConvertible {
    T1 Convert<T1, T2>(T2 arg);
}

The following code overrides the generic method Convert:

>>> import clr
>>> clr.AddReference("convert.dll")
>>> import System
>>> import IMyConvertible
>>>
>>> class MyConvertible(IMyConvertible):
...     def Convert(self, t2, T1, T2):
...         return T1(t2)
>>>
>>> o = MyConvertible()
>>> # Use Reflection to simulate a call from another .NET language
>>> type_params = System.Array[System.Type]([str, float])
>>> convert = clr.GetClrType(IMyConvertible).GetMethod("Convert")
>>> convert_of_str_float = convert.MakeGenericMethod(type_params)
>>> args = System.Array[object]([100.1])
>>> convert_of_str_float.Invoke(o, args)
'100.1'

Note

Generic method receive information about the method signature being invoked, whereas normal method overloads do not. The reason is that .NET does not allow normal method overloads to differ by the return type, and it is usually possible to determine the argument types based on the argument values. However, with generic methods, one of the type parameters may only be used as the return type. In that case, there is no way to determine the type paramter.

 

下边这段是说您能够把.Net类用Python的语法来实例化,也足以调用new方法来实例化,小编认为在python里new望着极度扭,仍然新故代谢吧。

It is sometimes desirable to invoke an instance method using the unbound class instance method and passing an explicit self object as the first argument. For example, .NET allows a class to declare an instance method with the same name as a method in a base type, but without overriding the base method. SeeSystem.Reflection.MethodAttributes.NewSlot for more information. In such cases, using the unbound class instance method syntax allows you chose precisely which slot you wish to call:

Value types

下边那第一次全国代表大会段说了一大堆,很复杂,机译困难,看了半天也不知她讲什么样,忖度:大致是在讲,在IronPython中并不是试图更正.Net类型中的值类型,不然会发生过多意料之外的结果

Python expects all mutable values to be represented as a reference type. .NET, on the other hand, introduces the concept of value types which are mostly copied instead of referenced. In particular .NET methods and properties returning a value type will always return a copy.

This can be confusing from a Python programmer’s perspective since a subsequent update to a field of such a value type will occur on the local copy, not within whatever enclosing object originally provided the value type.

While most .NET value types are designed to be immutable, and the .NET design guidelines recommend value tyeps be immutable, this is not enforced by .NET, and so there do exist some .NET valuetype that are mutable. TODO - Example.

For example, take the following C# definitions:

struct Point {
    # Poorly defined struct - structs should be immutable
    public int x;
    public int y;
}

class Line {
    public Point start;
    public Point end;

    public Point Start { get { return start; } }
    public Point End { get { return end; } }
}

If line is an instance of the reference type Line, then a Python programmer may well expect "line.Start.x = 1" to set the x coordinate of the start of that line. In fact the property Start returned a copy of the Point value type and it’s to that copy the update is made:

print line.Start.x    # prints ‘0’
line.Start.x = 1
print line.Start.x    # still prints ‘0’

This behavior is subtle and confusing enough that C# produces a compile-time error if similar code is written (an attempt to modify a field of a value type just returned from a property invocation).

Even worse, when an attempt is made to modify the value type directly via the start field exposed by Line (i.e. “`line.start.x = 1`”), IronPython will still update a local copy of the Point structure. That’s because Python is structured so that “foo.bar” will always produce a useable value: in the case above “line.start” needs to return a full value type which in turn implies a copy.

C#, on the other hand, interprets the entirety of the “`line.start.x = 1`” statement and actually yields a value type reference for the “line.start” part which in turn can be used to set the “x” field in place.

This highlights a difference in semantics between the two languages. In Python “line.start.x = 1” and “foo = line.start; foo.x = 1” are semantically equivalent. In C# that is not necessarily so.

So in summary: a Python programmer making updates to a value type embedded in an object will silently have those updates lost where the same syntax would yield the expected semantics in C#. An update to a value type returned from a .NET property will also appear to succeed will updating a local copy and will not cause an error as it does in the C# world. These two issues could easily become the source of subtle, hard to trace bugs within a large application.

In an effort to prevent the unintended update of local value type copies and at the same time preserve as pythonic and consistent a view of the world as possible, direct updates to value type fields are not allowed by IronPython, and raise a ValueError:

>>> line.start.x = 1 #doctest:  SKIP
Traceback (most recent call last):
   File , line 0, in input##7
ValueError Attempt to update field x on value type Point; value type fields can not be directly modified

This renders value types “mostly” immutable; updates are still possible via instance methods on the value type itself.

 

However, it is possible that the type has another method with the same name. In that case, the explicitly implemented method is not accessible as an attribute. However, it can still be called by using the unbound class instance method syntax:

也支撑命名参数

>>> import clr
>>> r = clr.Reference[float]()
>>> d.TryGetValue("b", r)
True
>>> r.Value
200.2
>>> import clr
>>> clr.AddReference("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")

在CLR引入.Net大类之后,就可以使用Python代码正式导入这些类,在IronPython中,会将这些.Net 转化为Python类来对待,但如果使用类示例对比,会发现无论你对比的是.Net类还是Python类,都成立。
可以使用import 直接导入命名空间下所有东西,也可以用from x import x【,x...】的语法选择性的导入个别需要被用到的类

>>> import System
>>> System #doctest:  ELLIPSIS
<module 'System' (CLS module, ... assemblies loaded)>
>>> System.Collections #doctest:  ELLIPSIS
<module 'Collections' (CLS module, ... assemblies loaded)>

Compiling Python code into an assembly

看不懂

The pyc sample can be used to compile IronPython code into an assembly. The sample builds on top of clr-CompileModules. The assembly can then be loaded and executed using Python-ImportModule. However, note that the MSIL in the assembly is not CLS-compliant and cannot be directly accessed from other .NET languages.

The types in the namespaces are exposed as Python types, and are accessed as attributes of the namespace. The following code accesses the System.Environment class from mscorlib.dll:

你也足避防强钦赐接下去的代码必需相配函数的哪一种重载,譬喻上边代码,最终三次计算只传入1个参数,那么将会报错

System.Object.ToString, __repr__ and __str__

>>> d = { "a":100.1, "b":200.2, "c":300.3 }
>>> from System.Collections.Generic import Dictionary
>>> d = Dictionary[str, float](d)
>>> d.TryGetValue("b")
(True, 200.2)
>>> d.TryGetValue("z")
(False, 0.0)

Proxy types

预计:大致是说在ironPython里不能直接使用C#里的System.MarshalByRefObject实例,不过能够通过非绑定类的实例来调用,那个文书档案通篇下来平日利用非绑定类这一个词,一贯看不驾驭毕竟指的是如何的类。

IronPython cannot directly use System.MarshalByRefObject instances. IronPython uses reflection at runtime to determine how to access an object. However, System.MarshalByRefObject instances do not support reflection.

You can use unbound-class-instance-method syntax to call methods on such proxy objects.

 

Properties

There is one important detail worth pointing out. IronPython tries to use the type library of the OleAut object if it can be found, in order to do name resolution while accessing methods or properties. The reason for this is that the IDispatch interface does not make much of a distinction between properties and method calls. This is because of Visual Basic 6 semantics where "excel.Quit" and "excel.Quit()" have the exact same semantics. However, IronPython has a strong distinction between properties and methods, and methods are first class objects. For IronPython to know whether "excel.Quit" should invoke the method Quit, or just return a callable object, it needs to inspect the typelib. If a typelib is not available, IronPython assumes that it is a method. So if a OleAut object has a property called "prop" but it has no typelib, you would need to write "p = obj.prop()" in IronPython to read the property value.

.NET Exceptions

raise语句扶植抛出.net和python中的非凡

raise can raise both Python exceptions as well as .NET exceptions:

>>> raise ZeroDivisionError()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError
>>> import System
>>> raise System.DivideByZeroException()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: Attempted to divide by zero.

except关键字也能够catch二种语言中的十分

The except keyword can catch both Python exceptions as well as .NET exceptions:

>>> try:
...    import System
...    raise System.DivideByZeroException()
... except System.DivideByZeroException:
...    print "This line will get printed..."
...
This line will get printed...
>>>

日前有一个例证讲过,尽管援用.Net对象,是不许删除和改过对象中的成员,在上边例子中,也同等,假使是python的不胜ZeroDivisionError,那么那是三个python类,允许专断纠正,例如在内部加三个foo属性,不过换来System.DivideByZeroException就

这一个了,因为那是一个.Net目的,假若希图改正,就能报错

IronPython implements the Python exception mechanism on top of the .NET exception mechanism. This allows Python exception thrown from Python code to be caught by non-Python code, and vice versa. However, Python exception objects need to behave like Python user objects, not builtin types. For example, Python code can set arbitrary attributes on Python exception objects, but not on .NET exception objects:

>>> e = ZeroDivisionError()
>>> e.foo = 1 # this works
>>> e = System.DivideByZeroException()
>>> e.foo = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'DivideByZeroException' object has no attribute 'foo'

下边这段写了一大堆,大约意思正是借使在IrinPython中,你写的是python代码,那只会catch到python类型的百般,.Net则是catch到.Net类型的百般,可是,通过捕获到的足够对象的clsException对象足以拿到三种语言公共的老大类,这是靠CLS(公共语言连串)来维护的。

To support these two different views, IronPython creates a pair of objects, a Python exception object and a .NET exception object, where the Python type and the .NET exception type have a unique one-to-one mapping as defined in the table below. Both objects know about each other. The .NET exception object is the one that actually gets thrown by the IronPython runtime when Python code executes a raise statement. When Python code uses the except keyword to catch the Python exception, the Python exception object is used. However, if the exception is caught by C# (for example) code that called the Python code, then the C# code naturally catches the .NET exception object.

The .NET exception object corresponding to a Python exception object can be accessed by using the clsException attribute (if the module has excecuted import clr):

>>> import clr
>>> try:
...     1/0
... except ZeroDivisionError as e:
...     pass
>>> type(e)
<type 'exceptions.ZeroDivisionError'>
>>> type(e.clsException)
<type 'DivideByZeroException'>

测算:上边这段差不离是说通过clsException对象中的Data能够索引到至极对应的Python版的非常

IronPython is also able to access the Python exception object corresponding to a .NET exception object [5], thought this is not exposed to the user [6].

[5]

The Python exception object corresponding to a .NET exception object is accessible (to the IronPython runtime) via the System.Exception.Data property. Note that this is an implementation detail and subject to change:

>>> e.clsException.Data["PythonExceptionInfo"] #doctest:  ELLIPSIS
<IronPython.Runtime.Exceptions.PythonExceptions ExceptionDataWrapper object at ...>

下边是2种语言的普遍十分类型对照表

[6] ... except via the DLR Hosting API ScriptEngine.GetService<ExceptionOperations>().GetExceptionMessage

Python exception

.NET exception

 

 

 

Exception

System.Exception

 

SystemExit

 

IP.O.SystemExit

StopIteration

System.InvalidOperationException subtype

 

StandardError

System.SystemException

 

KeyboardInterrupt

 

IP.O.KeyboardInterruptException

ImportError

 

IP.O.PythonImportError

EnvironmentError

 

IP.O.PythonEnvironmentError

IOError

System.IO.IOException

 

OSError

S.R.InteropServices.ExternalException

 

WindowsError

System.ComponentModel.Win32Exception

 

EOFError

System.IO.EndOfStreamException

 

RuntimeError

IP.O.RuntimeException

 

NotImplementedError

System.NotImplementedException

 

NameError

 

IP.O.NameException

UnboundLocalError

 

IP.O.UnboundLocalException

AttributeError

System.MissingMemberException

 

SyntaxError

 

IP.O.SyntaxErrorException (System.Data has something close)

IndentationError

 

IP.O.IndentationErrorException

TabError

 

IP.O.TabErrorException

TypeError

 

Microsoft.Scripting.ArgumentTypeException

AssertionError

 

IP.O.AssertionException

LookupError

 

IP.O.LookupException

IndexError

System.IndexOutOfRangeException

 

KeyError

S.C.G.KeyNotFoundException

 

ArithmeticError

System.ArithmeticException

 

OverflowError

System.OverflowException

 

ZeroDivisionError

System.DivideByZeroException

 

FloatingPointError

 

IP.O.PythonFloatingPointError

ValueError

ArgumentException

 

UnicodeError

 

IP.O.UnicodeException

UnicodeEncodeError

System.Text.EncoderFallbackException

 

UnicodeDecodeError

System.Text.DecoderFallbackException

 

UnicodeTranslateError

 

IP.O.UnicodeTranslateException

ReferenceError

 

IP.O.ReferenceException

SystemError

 

IP.O.PythonSystemError

MemoryError

System.OutOfMemoryException

 

Warning

System.ComponentModel.WarningException

 

UserWarning

 

IP.O.PythonUserWarning

DeprecationWarning

 

IP.O.PythonDeprecationWarning

PendingDeprecationWarning

 

IP.O.PythonPendingDeprecationWarning

SyntaxWarning

 

IP.O.PythonSyntaxWarning

OverflowWarning

 

IP.O.PythonOverflowWarning

RuntimeWarning

 

IP.O.PythonRuntimeWarning

FutureWarning

 

IP.O.PythonFutureWarning

 

上面又讲了一大堆,大约意思正是言传身教了眨眼之间间什么在一段代码中既捕获.Net万分又抓获Python相当,最后证实了二种特别在CLS中,其实.net才是堂弟,它才是参照他事他说加以考察标准。

Given that raise results in the creation of both a Python exception object and a .NET exception object, and given that rescue can catch both Python exceptions and .NET exceptions, a question arises of which of the exception objects will be used by the rescue keyword. The answer is that it is the type used in the rescue clause. i.e. if the rescue clause uses the Python exception, then the Python exception object will be used. If the rescue clause uses the .NET exception, then the .NET exception object will be used.

The following example shows how 1/0 results in the creation of two objects, and how they are linked to each other. The exception is first caught as a .NET exception. The .NET exception is raised again, but is then caught as a Python exception:

>>> import System
>>> try:
...     try:
...         1/0
...     except System.DivideByZeroException as e1:
...         raise e1
... except ZeroDivisionError as e2:
...     pass
>>> type(e1)
<type 'DivideByZeroException'>
>>> type(e2)
<type 'exceptions.ZeroDivisionError'>
>>> e2.clsException is e1
True

上边这段说的是假若Python顾客定义了叁个Python类世襲.Net的Exception对象,然后代码中抓获到了那几个极度,然后用.Net非常新闻的读取情势去会见拾贰分信息,你将什么也看不到,在下文中极其音信应该是"some message",不过用.net的格局访问,你只会见到

'Python Exception: MyException'

Python user-defined exceptions get mapped to System.Exception. If non-Python code catches a Python user-defined exception, it will be an instance of System.Exception, and will not be able to access the exception details:

>>> # since "Exception" might be System.Exception after "from System import *"
>>> if "Exception" in globals(): del Exception
>>> class MyException(Exception):
...     def __init__(self, value):
...         self.value = value
...     def __str__(self):
...         return repr(self.value)
>>> try:
...     raise MyException("some message")
... except System.Exception as e:
...     pass
>>> clr.GetClrType(type(e)).FullName
'System.Exception'
>>> e.Message
'Python Exception: MyException'

那么在.Net中调用IronPython脚本时,怎样能力搜查捕获脚本运营进度中抛出的Python万分呢?能够使用ScriptEngine.GetService<ExceptionOperations>(卡塔尔国.GetExceptionMessage方法来博取

In this case, the non-Python code can use the ScriptEngine.GetService<ExceptionOperations>().GetExceptionMessage DLR Hosting API to get the exception message.

 

TODO What happens if the sub-type has a static method with the same name but a different signature? Are both overloads available or not?

>>> from System.Guid import NewGuid, ToByteArray
>>> g = NewGuid()
>>> ToByteArray(g) #doctest:  ELLIPSIS
Array[Byte](...

Like Python static methods, the .NET static method can be accessed as an attribute of sub-types as well:

>>> int_bool_new = BitArray.__new__.Overloads[int, type(True)]
>>> ba = int_bool_new(BitArray, 5, True) # calls __new__(System.Int32, System.Boolean)
>>> ba = int_bool_new(BitArray, 5, "hello") # converts "hello" to a System.Boolan
>>> ba = int_bool_new(BitArray, 5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __new__() takes exactly 2 arguments (1 given)

Equality and hashing

TODO - This is currently just copied from IronRuby, and is known to be incorrect

Object equality and hashing are fundamental properties of objects. The Python API for comparing and hashing objects is __eq__ (and __ne__) and __hash__ respectively. The CLR APIs are System.Object.Equals and System.Object.GetHashCode respectively. IronPython does an automatic mapping between the two concepts so that Python objects can be compared and hashed from non-Python .NET code, and __eq__ and __hash__ are available in Python code for non-Python objects as well.

When Python code calls __eq__ and __hash__

  • If the object is a Python object, the default implementations of __eq__ and __hash__ get called. The default implementations call System.Object.ReferenceEquals and System.Runtime.CompileServices.RuntimeHelpers.GetHashCode respectively.
  • If the object is a CLR object, System.Object.Equals and System.Object.GetHashCode respectively get called on the .NET object.
  • If the object is a Python subclass object inheriting from a CLR class, the CLR's class's implementation of System.Object.Equals and System.Object.GetHashCode will get called if the Python subclass does not define __eq__ and __hash__. If the Python subclass defines __eq__ and __hash__, those will be called instead.

When static MSIL code calls System.Object.Equals and System.Object.GetHashCode

  • If the object is a Python objects, the Python object will direct the call to __eq__ and __hash__. If the Python object has implementations for these methods, they will be called. Otherwise, the default implementation mentioned above gets called.
  • If the object is a Python subclass object inheriting from a CLR class, the CLR's class's implementation of System.Object.Equals and System.Object.GetHashCode will get called if the Python subclass does not define __eq__ and __hash__. If the Python subclass defines __eq__ and __hash__, those will be called instead.

In many cases, the type parameter can be inferred based on the arguments passed to the method call. Consider the following use of a generic method [3]:

With generic type parameter inference, the last statement can also be written as:

IronPython also supports named arguments:

>>> from System.Collections import BitArray
>>> ba = BitArray(5)
>>> ba.Set(0, True) # call the Set method
>>> ba[0]
True

In such cases, IronPython tries to expose the method using its simple name - if there is no ambiguity:

The above two lines are equivalent to this single line:

>>> from System import EventHandler, EventArgs
>>> EventHandler # this is the combo type object
<types 'EventHandler', 'EventHandler[TEventArgs]'>
>>> # Access the non-generic type
>>> dir(EventHandler) #doctest:  ELLIPSIS
['BeginInvoke', 'Clone', 'DynamicInvoke', 'EndInvoke', ...
>>> # Access the generic type with 1 type paramter
>>> dir(EventHandler[EventArgs]) #doctest:  ELLIPSIS
['BeginInvoke', 'Call', 'Clone', 'Combine', ...


很多时候在IronPython 中并不支持一口气导入整个命名空间里所有东西

.NET types are exposed as Python classes, and you can do many of the same operations on .NET types as with Python classes. In either cases, you create an instance by calling the type:

推断:注意,借使传入的参数需求被举办1次以上的强转技巧找到匹配的话,那么将报错

.NET represents types using System.Type. However, when you access a .NET type in Python code, you get a Python type object [2]:

However, note that IronPython will raise a TypeError if there are conversions to more than one of the overloads:

You can import specific members, both static and instance:

Integration of Python and .NET features

下边这段差非常少是介绍 Python和.Net特征统生龙活虎化在IronPython中的一些反映,举个例子支持python的doc成效读.Net的API文书档案,又大概读不到就一向通过反射来读取一些有关那些类的消息

  • Type system integration.

    • See "Type-system unification (type and System.Type)"
    • Also see extensions-to-python-types and extensions-to-dotnet-types
  • List comprehension works with any .NET type that implements IList

  • with works with with any System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T>

  • pickle and ISerializable

  • __doc__ on .NET types and members:

    • __doc__ uses XML comments if available. XML comment files are installed if TODO. As a result, help can be used:

      >>> help(System.Collections.BitArray.Set) #doctest:  NORMALIZE_WHITESPACE
      Help on method_descriptor:
      Set(...)
          Set(self, int index, bool value)
                          Sets the bit at a specific
           position in the System.Collections.BitArray to
           the specified value.
      <BLANKLINE>
          index:
                          The zero-based index of the
           bit to set.
      <BLANKLINE>
          value:
                          The Boolean value to assign
           to the bit.
      
    • If XML comment files are not available, IronPython generates documentation by reflecting on the type or member:

      >>> help(System.Collections.Generic.List.Enumerator.Current) #doctest:  NORMALIZE_WHITESPACE
      Help on getset descriptor System.Collections.Generic in mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.Enumerator.Current:
      <BLANKLINE>
      Current
          Get: T Current(self)
      
    • Extensions to Python types

      import clr exposes extra functionality on some Python types to make .NET features accessible:

      • method objects of any builtin or .NET types:
        • instance method
          • Overloads(t1 [, t2...])
      • type objects
        • instance method
          • __getitem__(t1 [, t2...]) - creates a generic instantiation

上边显示的率先种是隐式的,直接调用方法,比如说原来.Net字典里的TryGetValue方法,原来要传播二个key和八个out援用参数,再次来到bool结果表示有没找到,可是在IronPython中隐式达成只要直接调用方法,传入key就行了,重回三个元组类型的重返值,里面包蕴了主意再次回到值和引用输出重返值。

Using COM objects

One you have access to a COM object, it can be used like any other objects. Properties, methods, default indexers and events all work as expected.

这段很难知晓,看不懂

也援救使用键值对字典给艺术传参(爽)

Methods with ref or out parameters

Python里未有有关的语法用来表示引用类型,假诺你用Python重写.Net中的方法,那么原本参数列表中的输出/援引类型将被分解为三个CL大切诺基援用类型,其实这些概念前面内容中有贰个例子里有涉及,看上面那几个事例你会发觉,在调用

python重写的办法时原来传出的特别参数群集中最终一个活动被定义为一个CL奥迪Q5引用类型,调用方法后,读取这一个指标的值就能够收获输出结果,相通,在重写方法的进度中,大家也非得以  参数名.Value的花样给那个CLHighlander引用类型的变量赋值

Python does not have syntax for specifying whether a method paramter is passed by-reference since arguments are always passed by-value. When overriding a .NET method with ref or out parameters, the ref or out paramter is received as a clr.Reference[T] instance. The incoming argument value is accessed by reading theValue property, and the resulting value is specified by setting the Value property:

>>> import clr
>>> import System
>>> StrFloatDictionary = System.Collections.Generic.IDictionary[str, float]
>>>
>>> class MyDictionary(StrFloatDictionary):
...     def TryGetValue(self, key, value):
...         if key == "yes":
...             value.Value = 100.1 # set the *out* parameter
...             return True
...         else:
...             value.Value = 0.0  # set the *out* parameter
...             return False
...     # Other methods of IDictionary not overriden for brevity
...
>>> d = MyDictionary()
>>> # Use Reflection to simulate a call from another .NET language
>>> tryGetValue = clr.GetClrType(StrFloatDictionary).GetMethod("TryGetValue")
>>> args = System.Array[object](["yes", 0.0])
>>> tryGetValue.Invoke(d, args)
True
>>> args[1]
100.1

In the explicit way, you can pass an instance of clr.Reference[T] for the ref or out argument, and its Value field will get set by the call. The explicit way is useful if there are multiple overloads with ref parameters:

This is an implementation detail.

>>> BitArray((1, 2, 3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Multiple targets could match: BitArray(Array[Byte]), BitArray(Array[bool]), BitArray(Array[int])
>>> from System.Collections import BitArray
>>> isinstance(ba, BitArray)
True

其他,那篇文书档案,也正是法定文书档案中实际只讲了怎么在Python里用.Net,以为那篇文书档案是写给Python开采者看的,但是很意外,在百度上也能搜到在.Net中利用Python的例子,不明白这几人的材料是从何地得来的,笔者搜遍了官方网址提供的有着文书档案和wiki始终

Non-automation COM objects

IronPython does not fully support COM objects which do not support dispinterfaces since they appear likey proxy objects [12]. You can use the unbound class method syntax to access them.

[12] This was supported in IronPython 1, but the support was dropped in version 2.

 

再以往几条内容不怎么首要了就不抄进来了,本篇笔记到此甘休

The unification also extends to other type system entities like methods. .NET methods are exposed as instances of method:

.Net的静态方法会以Python的平整,方法会被认为是一个类的叁本质量,猜想:上面那2个类的同名方法如若实现是千篇风华正茂律的,那么相比较起来结果正是如出意气风发辙的

类似支撑输入更详实的程序集音信来导入钦定版本的.Net类

.NET supports overloading methods by both number of arguments and type of arguments. When IronPython code calls an overloaded method, IronPython tries to select one of the overloads at runtime based on the number and type of arguments passed to the method, and also names of any keyword arguments. In most cases, the expected overload gets selected. Selecting an overload is easy when the argument types are an exact match with one of the overload signatures:

Note that if you import a static property, you will import the value when the import executes, not a named object to be evaluated on every use as you might mistakenly expect:

>>> SpecialFolder is System.Environment.SpecialFolder
True

Creating a COM object

怎么使用COM对象

Different languages have different ways to create a COM object. VBScript and VBA have a method called CreateObject to create an OleAut object. JScript has a method called TODO. There are multiple ways of doing the same in IronPython.

  1. The first approach is to use System.Type.GetTypeFromProgID and System.Activator.CreateInstance . This method works with any registered COM object:

    >>> import System
    >>> t = System.Type.GetTypeFromProgID("Excel.Application")
    >>> excel = System.Activator.CreateInstance(t)
    >>> wb = excel.Workbooks.Add()
    >>> excel.Quit()
    
  2. The second approach is to use clr.AddReferenceToTypeLibrary to load the type library (if it is available) of the COM object. The advantage is that you can use the type library to access other named values like constants:

    >>> import System
    >>> excelTypeLibGuid = System.Guid("00020813-0000-0000-C000-000000000046")
    >>> import clr
    >>> clr.AddReferenceToTypeLibrary(excelTypeLibGuid)
    >>> from Excel import Application
    >>> excel = Application()
    >>> wb = excel.Workbooks.Add()
    >>> excel.Quit()
    
  3. Finally, you can also use the interop assembly. This can be generated using the tlbimp.exe tool. The only advantage of this approach was that this was the approach recommeded for IronPython 1. If you have code using this approach that you developed for IronPython 1, it will continue to work:

    >>> import clr
    >>> clr.AddReference("Microsoft.Office.Interop.Excel")
    >>> from Microsoft.Office.Interop.Excel import ApplicationClass
    >>> excel = ApplicationClass()
    >>> wb = excel.Workbooks.Add()
    >>> excel.Quit()
    
>>> import System
>>> System.ICloneable.Clone("hello") # same as : "hello".Clone()
'hello'

See appendix for the detailed rules.

Properties with parameters

COM and VB.NET support properties with paramters. They are also known as non-default indexers. C# does not support declaring or using properties with parameters.

IronPython does support properties with parameters. For example, the default indexer above can also be accessed using the non-default format as such:

>>> ba.Item[0]
False

.net的事件能够行使 = 和-=的样式开展注册和卸载,在IronPython中相近支撑这种耍法,上边包车型地铁代码里用python 代码遵照.Net的格式定义了叁个回调函数,居然也能注册到.Net事件里去,真爽

.NET events are exposed as objects with __iadd__ and __isub__ methods which allows using  = and -= to subscribe and unsubscribe from the event. The following code shows how to subscribe a Python function to an event using  =, and unsubscribe using -=

>>> from System.IO import FileSystemWatcher
>>> watcher = FileSystemWatcher(".")
>>> def callback(sender, event_args):
...     print event_args.ChangeType, event_args.Name
>>> watcher.Created  = callback
>>> watcher.EnableRaisingEvents = True
>>> import time
>>> f = open("test.txt", "w "); time.sleep(1)
Created test.txt
>>> watcher.Created -= callback
>>>
>>> # cleanup
>>> import os
>>> f.close(); os.remove("test.txt")

You can also subscribe using a bound method:

您也足以如此写,上面代码把回调写在四个类里头而已,认为并未什么卵用,看起来更麻烦了

>>> watcher = FileSystemWatcher(".")
>>> class MyClass(object):
...     def callback(self, sender, event_args):
...         print event_args.ChangeType, event_args.Name
>>> o = MyClass()
>>> watcher.Created  = o.callback
>>> watcher.EnableRaisingEvents = True
>>> f = open("test.txt", "w "); time.sleep(1)
Created test.txt
>>> watcher.Created -= o.callback
>>>
>>> # cleanup
>>> f.close(); os.remove("test.txt")

You can also explicitly create a delegate instance to subscribe to the event. Otherwise, IronPython automatically does it for you. [4]:

也得以来得定义三个信托

>>> watcher = FileSystemWatcher(".")
>>> def callback(sender, event_args):
...     print event_args.ChangeType, event_args.Name
>>> from System.IO import FileSystemEventHandler
>>> delegate = FileSystemEventHandler(callback)
>>> watcher.Created  = delegate
>>> watcher.EnableRaisingEvents = True
>>> import time
>>> f = open("test.txt", "w "); time.sleep(1)
Created test.txt
>>> watcher.Created -= delegate
>>>
>>> # cleanup
>>> f.close(); os.remove("test.txt")

他说展现定义委托能够使程序内存占用更加少,不知为啥。。。难道他指的是装箱和拆箱进度的本性损耗?

The only advantage to creating an explicit delegate is that it is uses less memory. You should consider it if you subscribe to lots of events, and notice excessive System.WeakReference objects.

 

上边这段入眼体现了怎么利用python语法实例化.net数组和索引数组中的值

IronPython supports indexing of System.Array with a type object to access one-dimensional strongly-typed arrays:

>>> System.Array[int]
<type 'Array[int]'>

IronPython also adds a __new__ method that accepts a IList<T> to initialize the array. This allows using a Python list literal to initialize a .NET array:

>>> a = System.Array[int]([1, 2, 3])

Further, IronPython exposes __getitem__ and __setitem__ allowing the array objects to be indexed using the Python indexing syntax:

>>> a[2]
3

一经用GetValue索引多少个负数,会报错,你一定要像a[-1]这种索引格局才不会报错

Note that the indexing syntax yields Python semantics. If you index with a negative value, it results in indexing from the end of the array, whereas .NET indexing (demonstrated by calling GetValue below) raises a System.IndexOutOfRangeException exception:

>>> a.GetValue(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: Index was outside the bounds of the array.
>>> a[-1]
3

如出后生可畏辙也支持python 中的数组分割语法

Similarly, slicing is also supported:

>>> a[1:3]
Array[int]((2, 3))
Python argument type .NET method parameter type
int System.Int8, System.Int16
float System.Float
tuple with only elements of type T System.Collections.Generic.IEnumerable<T>
function, method System.Delegate and any of its sub-classes

Hashing of mutable objects

The CLR expects that System.Object.GetHashCode always returns the same value for a given object. If this invariant is not maintained, using the object as a key in a System.Collections.Generic.Dictionary<K,V> will misbehave. Python allows __hash__ to return different results, and relies on the user to deal with the scenario of using the object as a key in a Hash. The mapping above between the Python and CLR concepts of equality and hashing means that CLR code that deals with Python objects has to be aware of the issue. If static MSIL code uses a Python object as a the key in a Dictionary<K,V>, unexpected behavior might happen.

To reduce the chances of this happenning when using common Python types, IronPython does not map __hash__ to GetHashCode for Array and Hash. For other Python classes, the user can provide separate implementations for __eq__ and Equals, and __hash__ and GetHashCode if the Python class is mutable but also needs to be usable as a key in a Dictionary<K,V>.

她还扶持字典式传参,那招在.Net里是未曾的,通过上边这么些事例你会开掘,你能够在采用进度中稳步搜罗参数,遵照顺序放入群集里,最终再丢进二个办法。

In the implicit way, an argument is passed normally to the method call, and its (potentially) updated value is returned from the method call along with the normal return value (if any). This composes well with the Python feature of multiple return values. System.Collections.Generic.Dictionary has a method bool TryGetValue(K key, out value). It can be called from IronPython with just one argument, and the call returns a tuple where the first element is a boolean and the second element is the value (or the default value of 0.0 if the first element is False):

The unbound class instance method syntax results in a virtual call, and calls the most derived implementation of the virtual method slot:

>>> from Microsoft.Win32 import Registry
>>> rkey = Registry.CurrentUser.OpenSubKey("Software")
>>> rkey.Dispose()
>>> System.GC.Collect()

Enumerations

下边是枚举类型的使用示例

.NET enumeration types are sub-types of System.Enum. The enumeration values of an enumeration type are exposed as class attributes:

print System.AttributeTargets.All # access the value "All"

IronPython also supports using the bit-wise operators with the enumeration values:

也协助 位操作符

>>> import System
>>> System.AttributeTargets.Class | System.AttributeTargets.Method
<enum System.AttributeTargets: Class, Method>

The argument types do not have be an exact match with the method signature. IronPython will try to convert the arguments if an unamibguous conversion exists to one of the overload signatures. The following code calls __new__(System.Int32) even though there are two constructors which take one argument, and neither of them accept a float as an argument:

>>> from System.Collections import BitArray
>>> ba = BitArray(5) # calls __new__(System.Int32)
>>> ba = BitArray(5, True) # calls __new__(System.Int32, System.Boolean)
>>> ba = BitArray(ba) # calls __new__(System.Collections.BitArray)

Calling base constructor

尽管你想让八个世襲自.net的python子类调用它基类的布局函数,那你须求像下边那样重写叁个*args参数的__new__组织,然后自身写一批决断去调用基类的组织重载。。。

那篇文书档案看见此间,我觉着用IronPython,我们假如调.net就好了,不要去改写它。。。那会给您带来众多不要求的难为。。。尽恐怕用.net去写代码给python调,不要在python里写.net,太难为了,破规矩比很多

.NET constructors can be overloaded. To call a specific base type constructor overload, you need to define a __new__ method (not __init__) and call __new__ on the .NET base type. The following example shows how a sub-type of System.Exception choses the base constructor overload to call based on the arguments it receives:

>>> import System
>>> class MyException(System.Exception):
...     def __new__(cls, *args):
...        # This could be implemented as:
...        #     return System.Exception.__new__(cls, *args)
...        # but is more verbose just to make a point
...        if len(args) == 0:
...            e = System.Exception.__new__(cls)
...        elif len(args) == 1:
...            message = args[0]
...            e = System.Exception.__new__(cls, message)
...        elif len(args) == 2:
...            message, inner_exception = args
...            if hasattr(inner_exception, "clsException"):
...               inner_exception = inner_exception.clsException
...            e = System.Exception.__new__(cls, message, inner_exception)
...        return e
>>> e = MyException("some message", IOError())
>>> args = [2, True] # list of arguments
>>> ba.Set(*args)
>>> ba[2]
True

dynamic

预计:因为有在.Net里用过IronPython,这段能够这么敞亮,就说在.Net里推行IronPython代码,即使重临值是叁个ironpython对象,可能你要从.Net访谈一个ironPython对象,那您要用三个dynamic类型的变量来收纳

Starting with .NET 4.0, C# and VB.Net support access to IronPython objects using the dynamic keyword. This enables cleaner access to IronPython objects. Note that you need to use the hosting-apis to load IronPython code and get the root object out of it.

However, properties are not imported:

TODO - Example of indexing Overloads with an Array, byref, etc using Type.MakeByrefType

Declaring .NET types

在IronPython中生机勃勃律协理.net中的函数重载,解释器会自动相配最切合的相当重载

Just like with normal Python modules, you can also use all the other forms of import as well:

Extensions to .NET types

测算:这段差不离是在介绍.Net被引进到ironPython后被扩张了一些方式,使其更为Python化

IronPython also adds extensions to .NET types to make them more Pythonic. The following instance methods are exposed on .NET objects (and .NET classes where explicitly mentioned):

  • Types with op_Implicit

    • TODO
  • Types with op_Explicit

    • TODO
  • Types inheriting from a .NET class or interface

    .NET base-type

    Synthesized Python method(s)

    System.Object

    all methods of object eg. __class__, __str__, __hash__, __setattr__

    System.IDisposable

    __enter__, __exit__

    System.Collections.IEnumerator

    next

    System.Collections.ICollection System.Collections.Generic.ICollection<T>

    __len__

    System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> System.Collections.IEnumerator System.Collections.Generic.IEnumerator<T>

    __iter__

    System.IFormattable

    __format__

    System.Collections.IDictionary System.Collections.Generic.IDictionary<TKey, TValue> System.Collections.Generic.ICollection<T> System.Collections.Generic.IList<T> System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> System.Collections.IEnumerator System.Collections.Generic.IEnumerator<T>

    __contains__

    System.Array

    • Class methods:
      • Indexing of the type object with a type object to access a specific array type
      • __new__(l) where l is IList<T> (or supports __getitem__?)
    • __getitem__, __setitem__, __slice__

    System.Delegate

    • Class method : __new__(type, function_or_bound_method)
    • __call__

    System.Enum

    __or__ TODO ?

  • Types with a .NET operator method name

    .NET operator method

    Synthesized Python method

    op_Addition, Add

    __add__

    Compare

    __cmp__

    get_<Name> [8]

    __getitem__

    set_<Name> [9]

    __setitem__

[8] where the type also has a property <Name>, and a DefaultMemberAttribute for <Name>
[9] where the type also has a property <Name>, and a DefaultMemberAttribute for <Name>

 

猜猜:上边这段大致是讲.Net里方法的落到实惩罚为显式和隐式两种,比方说在.Net里要是显式达成格局,那么大家只可以用接口技巧调用,假如隐式达成,那么直接在落到实处类还是接口中都能够调用。

>>> args = { "index" : 3, "value" : True }
>>> ba.Set(**args)
>>> ba[3]
True

IronPython also supports keyword arguments:

>>> from System.DateTime import Now
>>> Now #doctest:  ELLIPSIS
<System.DateTime object at ...>
>>> # Let's make it even more obvious that "Now" is evaluated only once
>>> a_second_ago = Now
>>> import time
>>> time.sleep(1)
>>> a_second_ago is Now
True
>>> a_second_ago is System.DateTime.Now
False

本文由金沙澳门官网发布于网络编程,转载请注明出处:Integration官方文档翻译笔记

关键词: 金沙澳门官网

上一篇:常用函数综合收拾
下一篇:没有了