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 | kr...@wintellect.com
> www.wintellect.com
> 
> 
> -----Original Message-----
> From: ironpython-users-bounces+rome=wintellect....@python.org 
> [mailto:ironpython-users-bounces+rome=wintellect....@python.org] On Behalf Of 
> Hernán Foffani
> Sent: Tuesday, September 27, 2011 6:43 AM
> Cc: ironpython-users@python.org
> 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 | kr...@wintellect.com www.wintellect.com
>> 
>> 
>> -----Original Message-----
>> From: ironpython-users-bounces+rome=wintellect....@python.org 
>> [mailto:ironpython-users-bounces+rome=wintellect....@python.org] On 
>> Behalf Of Hernán Foffani
>> Sent: Monday, September 26, 2011 1:36 PM
>> To: ironpython-users@python.org
>> 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: ironpython-users@python.org
>>> 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
>>> Ironpython-users@python.org
>>> http://mail.python.org/mailman/listinfo/ironpython-users
>>> 
>> 
>> _______________________________________________
>> Ironpython-users mailing list
>> Ironpython-users@python.org
>> http://mail.python.org/mailman/listinfo/ironpython-users
>> 
>> 
> 
> _______________________________________________
> Ironpython-users mailing list
> Ironpython-users@python.org
> http://mail.python.org/mailman/listinfo/ironpython-users
> 
> 

_______________________________________________
Ironpython-users mailing list
Ironpython-users@python.org
http://mail.python.org/mailman/listinfo/ironpython-users

Reply via email to