Passion * Technology * Ruthless Competence

Monday, April 28, 2008

Importing Static Methods with IPy

Like .NET, Python uses namespaces to avoid name collisions. However, the semantics are a bit different. If you want to use a type or function from a a given namespace in Python, you have to import it into your current scope. For example, if you want to use the Python datetime built-in module, you would import it into the current scope and use it like this:

import datetime
bush_last_day = datetime.date(2009,1,20)

Notice that when I import a Python module this way, it's scoped into it's namespace, which forces me to use the entire namespace scoped name to access the type. Of course, that gets tedious quickly, so Python provides a way to import a type from a specific namespace into your current scope like this:

from datetime import date
bush_last_day = date(2009,1,20)

With IronPython, you can do import .NET namespaces as well. Here's that same code using the standard .NET DateTime class.

from System import DateTime
bush_last_day = DateTime(2009,1,20)

What I didn't know is that you can import static methods & properties from .NET types into the current scope using the same syntax. Here's an example:

from System.DateTime import Now

if Now >= bush_last_day:
    print 'celebrate'
else:
    print (bush_last_day - Now).Days, 'days left'

Being able to import a static method into the current scope is pretty convenient. Thanks to my teammate Jimmy for cluing me into this IPy feature.

One caveat though: in Python, you can import an entire namespace into your current scope. You can do that with .NET namespaces, but not with .NET types

from datetime import *         # this works
from System import *           # so does this
from System.DateTime import# this doesn't work

Update: Michael Foord pointed out that if you import Now as I describe above, it places a DateTime object representing the time you imported it into local scope, rather than placing the underlying get_Now static method in local scope. So while DateTime.Now always returns a new value, Now never changes. Sounds like an IPy bug to me, but I'll have to circle back with the team to be sure.

Posted By Harry Pierson at 3:09 PM Pacific Daylight Time
Monday, April 28, 2008 2:38:56 PM (Pacific Standard Time, UTC-08:00)
Well... personally I think it is a terrible abuse of the import mechanism. LOL :-)
Monday, April 28, 2008 3:30:23 PM (Pacific Standard Time, UTC-08:00)
I was mostly being a troublemaker with that comment, but I know that this feature has confused at least one IronPython user.

He did exactly as you did in your example:

from System.DateTime import Now

and was then surprised that when he used Now it didn't update as it should. This is because in Python you can't use the import machinery to access static members on classes.

When you import a class method from IronPython you are doing something not normally possible from Python - so what is actually happening may not be immediately obvious to anyone reading the code.
Monday, April 28, 2008 7:26:20 PM (Pacific Standard Time, UTC-08:00)
No, I'd say that might be a bug. For example, if you import the static DateTime.Parse method, it works as you would expect. IPy appears to be placing the result if calling get_Now in the local scope, rather than the get_Now static method. I need to circle back with the team, but that seems wrong to me.

I opened up a CodePlex bug for it. http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=16323
DevHawk
Monday, May 05, 2008 11:35:59 AM (Pacific Standard Time, UTC-08:00)
I have this simple code. But it returns an error:
"TypeError: expected ProcessPriorityClass, got int"

from System.Diagnostics import Process
procs = Process.GetProcesses()
for p in procs:
if p.ProcessName == 'notepad':
print p.BasePriority
p.PriorityClass = 8

I thought one of the main points of ironpython is not have to worry about typing variables. But this seems to imply unless I do some sort of dim x as ProcessPriorityClass, I can't call set the value of PriorityClass.

I have searched hard for the answer to this, but it seems like maybe IP isn't that widely used yet. If you have some good links to where to go to get more help with IP that would be nice.
Thanks,
Matt
matt
Monday, May 05, 2008 12:59:37 PM (Pacific Standard Time, UTC-08:00)
IronPython is dynamically typed, but the underlying types from the .NET framework are still statically typed. IronPython won't auto convert an integer into an enumerated type, which is why you're getting a type exception. BasePriority is an integer, but it's read only. PriorityClass is read/write, but it takes a ProcessPriorityClass enum value.

You could write the code this way:

from System.Diagnostics import Process, ProcessPriorityClass
procs = Process.GetProcesses()
for p in procs:
__if p.ProcessName == 'notepad':
____print p.BasePriority
____p.PriorityClass = ProcessPriorityClass.BelowNormal

Note, I need to figure out how to get significant whitespace to work in comments. In the meantime, I'm using underscore as space in the code above.
DevHawk
Tuesday, May 06, 2008 3:17:48 AM (Pacific Standard Time, UTC-08:00)
Well that worked for me. It's actually pretty amazing what can be done with a few lines of code.

As per your original topic, I did import Process from System.Diagnostics. I figured ProcessPriorityClass was part of Process.

Is there a simple way to know what all is included when you import or try to import a .Net class.

Thanks
Matt
Tuesday, May 06, 2008 10:19:31 AM (Pacific Standard Time, UTC-08:00)
Yep, use Python's built in dir function. You can also use the built-in help function to retrieve the built-in help and method signature for types and methods.

from System import Diagnostics
dir(Diagnostics.Process)
dir(Diagnostics.Process.PriorityClass)
help(Diagnostics.Process.GetProcesses)

DevHawk
Comments are closed.
TechEd New Zealand
TechEd Australia

PDC08

patterns & practices
Summit 2008

Change Congress
Recent Bookmarks
Tags .NET Framework (2) ADO.NET (5) Agile (7) AJAX (3) Architecture (283) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (93) Web Services (5) ASP.NET (22) Battlestar Galactica (3) BI (2) BizTalk (4) Blogging (114) dasBlog (11) Podcasting (4) BPM (1) C# (6) C++ (4) Capitals (5) CardSpace (3) CLR (2) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Dependency Injection (2) Development (115) C Plus Plus (1) Embedded (5) Lanugages (37) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (12) Domain Specific Languages (13) Durable Messaging (5) Dynamic Languages (9) Dynamic Silverlight (1) Education (3) Enterprise 2.0 (1) Entertainment (14) ETech (15) F# (42) Functional Programming (12) Game Development (2) Guidance Automation (3) Hardware (8) HawkEye (3) Hockey (29) Home Electronics (1) Home Network (5) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (19) IronRuby (7) Java (2) Job (3) LINQ (19) Live Mesh (1) Lost (1) Master Data Management (1) Media 2.0 (6) Microsoft (28) MIX06 (2) Mobile Phone (1) Morning Coffee (170) Object Oriented (4) Office (5) Open Source (4) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (30) Games (18) General Geekery (26) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (15) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (1) Politics (39) PowerPoint (2) PowerShell (30) Presentation (5) Projects (1) HawkWiki (1) Python (4) Quote of the Day (4) Refactoring (1) Research (2) REST (18) Reuse (5) Robotics (1) Rome (5) Ruby (23) Sci-Fi (2) Scripting (4) Security (3) Service Broker (14) SharePoint (2) Silverlight (15) Social Software (1) Software + Services (2) Software Factories (11) Software Industry (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (6) Unified Client (1) Unit Testing (4) UX (1) Virtual PC (2) Visual Basic (1) Visual Studio (20) Volta (2) Washington Capitals (34) WCF (31) Web 2.0 (64) Web Services (5) WF (20) Windows Live (23) Xbox (1) Xbox 360 (53) XML (7) XNA (13)
Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion.