El 27/09/2011, a las 16:54, Keith Rome escribió:
> Just beware that if you use this same mechanism to introspect CLR objects, it
> can return member names for static and protected members in addition to the
> public instance members (and attempts to access those members might fail). To
> work around this, I first use reflection to get a list of static or protected
> CLR members and then exclude those member names from the list returned by
> Operations.GetMemberNames(). For Python objects, this doesn't seem to cause
> any complications, since reflection does not know anything about the dynamic
> members.
My use case is pure Python objects, and right now a couple of C# lines solved
it.
>
> Doing it that way allows the same code to operate correctly in a
> heterogeneous environment, where some objects might originate from a dynamic
> scope while others originate from a static managed scope.
Interesting. I might use it in case our users decided to extend our application
by using IP and pure .NET dlls.
So far nobody did that, but who knows....
Thanks again,
-Hernán.
>
> Example (I am sure there are ways to tighten this up, but it gets the job
> done):
>
> IEnumerable<string> GetMemberNames(dynamic obj)
> {
> // use reflection first so we can exclude anything that will just fail
> under the dynamic context
> var objType = ((object)obj).GetType();
> var staticMembers = objType.GetMembers(BindingFlags.FlattenHierarchy |
> BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
> var privateMembers = objType.GetMembers(BindingFlags.Instance |
> BindingFlags.NonPublic);
> var excludedMembers = staticMembers.Union(privateMembers).Select(member =>
> member.Name).OrderBy(name => name).Distinct();
>
> var langContext =
> HostingHelpers.GetLanguageContext(_scriptService.GetScriptEngine());
> try
> {
> IList<string> members;
>
> try
> {
> members = langContext.Operations.GetMemberNames(obj);
> }
> catch (AmbiguousMatchException)
> {
> members = langContext.Operations.GetMemberNames((object)obj);
> }
>
> members = members.Except(excludedMembers).ToList();
>
> // ... I do some more work here to filter out members that start with
> underbar
> // character or that resolve to types that don't make sense for my
> purposes (events, etc)
>
> return members;
> }
> catch (Exception)
> {
> return new string[] { };
> }
> }
>
>
> Keith Rome
> Senior Consultant and Architect
> MCPD-EAD, MCSD, MCDBA, MCTS-WPF, MCTS-TFS, MCTS-WSS
> Wintellect | 770.617.4016 | [email protected]
> www.wintellect.com
>
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of
> Hernán Foffani
> Sent: Tuesday, September 27, 2011 6:43 AM
> Cc: [email protected]
> Subject: Re: [Ironpython-users] instropection in an embedded engine
>
> You are right. It was the all the Operations thing what I was missing
> altogether, silly me.
> Now it all make sense.
> Thanks a lot.
>
> El 26/09/2011, a las 19:57, Keith Rome escribió:
>
>> If you are just trying to enumerate members of a python object, and possibly
>> invoke them, then wouldn't a LanguageContext's DynamicOperations get the job
>> done? Perhaps I am misunderstanding your objectives though.
>>
>> HostingHelpers.GetLanguageContext(ScriptEngine) to get the LanguageContext,
>> and then just use the Operations property from that. This gives you
>> introspection methods for GetMemberNames() and a number of invocation
>> mechanisms. All you need is a reference to an object to inspect and the
>> language engine that owns it (or one that is compatible with it).
>>
>> In my implementation of a Watches/Locals/Modules UI for a python debugger, I
>> use that procedure as the basis for routines that populate the inspector
>> grids. Basically, whenever the user reaches a breakpoint via my settrace()
>> hook, I inspect the members of all variables in the current scope and
>> refresh a visual tree (really a grid with indentation), and as they drill
>> down into those objects I just walk down one step further into the data
>> structure. It isn't the fastest thing in the world, but then again it
>> doesn't have to be - the script is effectively paused until I allow the
>> breakpoint to resume.
>>
>>
>> Keith Rome
>> Senior Consultant and Architect
>> MCPD-EAD, MCSD, MCDBA, MCTS-WPF, MCTS-TFS, MCTS-WSS Wintellect |
>> 770.617.4016 | [email protected] www.wintellect.com
>>
>>
>> -----Original Message-----
>> From: [email protected]
>> [mailto:[email protected]] On
>> Behalf Of Hernán Foffani
>> Sent: Monday, September 26, 2011 1:36 PM
>> To: [email protected]
>> Subject: Re: [Ironpython-users] instropection in an embedded engine
>>
>> Thanks, I'm getting closer.
>> Now I'm trying to find how to get a (new? current?) CodeContext to, for
>> instance, call DictProxy.keys(..) The public constructor of CodeContext
>> signature (a PythonDictionary and a ModuleContext) doesn't match the
>> examples I could find (ScriptScope, LanguageContext).
>>
>> Does anyone know of any examples of introspection of a hosted IP scripting
>> from C#?
>> Evidently there's a lot I'm missing here and would like to do the due
>> homework first.
>>
>> I'm using NET 4 and don't need 2.x compatibility.
>>
>> Regards,
>> -Hernán
>>
>> El 23/09/2011, a las 21:43, Dino Viehland escribió:
>>
>>> __class__ exists on object in python and is then inherited by the
>>> other types. When accessing a member from C# you get its view of the world
>>> which doesn't include Python object members. To get the Python type I
>>> suggest calling DynamicHelpers.GetPythonType.
>>>
>>> Sent from my Windows Phone
>>>
>>> -----Original Message-----
>>> From: Hernán Foffani
>>> Sent: Friday, September 23, 2011 9:12 AM
>>> To: [email protected]
>>> Subject: [Ironpython-users] instropection in an embedded engine
>>>
>>>
>>> Having the following Python code:
>>>
>>> class Plugin:
>>> def method(self):
>>> pass
>>> plugin = Plugin()
>>>
>>> and an embedded ScriptScope instance in my .NET application, the
>>> following C# works fine
>>>
>>> dynamic plugin = pythonEngine.GetVariable("plugin");
>>> var attrs = plugin.__class__.__dict__;
>>>
>>> if Plugin python class was defined as an old-style class, but fails
>>> if Plugin inherits from object (__class__ non existent).
>>>
>>> Under the VS debugger the dynamic object plugin shows as having three
>>> attributes .class, .dict and .slots_and_weakref (with dots in their
>>> names) but no __class__ or __dict__.
>>>
>>> I found that I could do something like
>>> plugin.method.im_class.__dict__ but I'd rather stick with the common idiom.
>>>
>>> Is it a known issue? Something related to the way I'm using the engine?
>>>
>>> Thanks in advance,
>>> -Hernán.
>>>
>>> _______________________________________________
>>> Ironpython-users mailing list
>>> [email protected]
>>> http://mail.python.org/mailman/listinfo/ironpython-users
>>>
>>
>> _______________________________________________
>> Ironpython-users mailing list
>> [email protected]
>> http://mail.python.org/mailman/listinfo/ironpython-users
>>
>>
>
> _______________________________________________
> Ironpython-users mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/ironpython-users
>
>
_______________________________________________
Ironpython-users mailing list
[email protected]
http://mail.python.org/mailman/listinfo/ironpython-users