# How access UserDictionary in Python?

**URL:** <https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267>\
**Category:** Scripting\
**Tags:** python\
**Created:** [March 16, 2017, 12:18pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267 "2017-03-16T12:18:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 12:18pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/1 "2017-03-16T12:18:25Z")

</div>

OK, I didn’t sleep last night because the following drives me nuts: How can I access the UserDictionary with PythonScript of :

1. a Rhino object selected by the user,
2. or a Brep, or Geometry in GH (what is the difference BTW?)

For the Rhino object I tried things the following for hours, but no matter what I try I get the error message “_`Message: 'builtin_function_or_method' object has no attribute 'UserDictionary'`_”

```
obj = Rhino.Input.Custom.GetObject()
obj.SetCommandPrompt("Select objects")
... blah, blah

for i in range(obj.ObjectCount):
    # Nope:
    o = obj.Object(i)
    o.UserDictionary.Set("KEY", "VALUE") <-- Nope, error
    # Nope:
    g = o.Geometry
    g.UserDictionary.Set("KEY", "VALUE") <-- Nope, error
    # Sigh....

```

Nada. I picked a solid Box and a Sphere, but no UserDictionary.

Obviously I have no idea how the basic concept works. I’ve created zillions of getters and setters in my life, and key value pairs isn’t exactly rocket science, so that’s not the problem, but where is the friggin dictionary? (And yes, I see them in the documentation but nowhere to be found in the code… 🙂 )

And BTW, what is a ‘Geometry’ as opposed to an “Object” in Rhino (the difference)? And despite the difference, shouldn’t both have the UserDictionary?

OK, perhaps I need some sleep, but if anyone has a python code snippet to share, please. And explain the concept (which should be obvious, I mean, if you just find the dict… )

// Rolf

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [March 16, 2017, 12:30pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/2 "2017-03-16T12:30:18Z")

</div>

Hi Rolf

hmmm …  
in RhinoCommon both GeometryBase and ObjectAttributes have GetUserString() and SetUserString() methods.  
Are you talking of something else ?

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 12:36pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/3 "2017-03-16T12:36:50Z")

</div>

> [@emilio](#):
>
> GetUserString() and SetUserString()

… and UserDictionary. Are they the same thing? I find the form `UserDictionary.Set("key", "value")` in the documentation. When I try `GetUserString()` and `SetUserString()` in the code above I get the same message: “`Message: 'builtin_function_or_method' object has no attribute 'GetUserString'`”

I’m entirely lost.

// Rolf

---

<div class="post-metadata">

**Author:** ![MarcusStrube](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/marcusstrube/32/393776_2.png) [@MarcusStrube](https://discourse.mcneel.com/u/MarcusStrube)\
**Post date:** [March 16, 2017, 12:45pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/4 "2017-03-16T12:45:21Z")

</div>

I cannot really answer your question, but generally things work as you expect them to work. You just seem to look in the wrong place: [UserDictionary.gh](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/1/e/1e8cbd8cf1b212f11216f0d89b8c4ee45f3f1d2d.gh) (5.0 KB)

 ![](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/c/e/ce7a2b595f52c5793c25a35c523293e5353fdcda.png)

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 12:56pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/5 "2017-03-16T12:56:21Z")

</div>

The Breps in GH is OK, but where I prove to be RILStupid™ is with the regular PythonScript. 🙂

Now, what is a “Brep” as opposed to “Object” as opposed to “Geometry” in PythonScript… ? Can I cast from one to another, etc?

The secret enabling one to look in the right place is to have an overview of the general concepts I guess. I lack this overview.

**UML?**  
If there where a UML diagram somewhere explaining the basic concepts, that would help a lot. The individual inheritance chains as presented in the documentation doesn’t explain much about how things relate to each other

// Rolf

---

<div class="post-metadata">

**Author:** ![MarcusStrube](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/marcusstrube/32/393776_2.png) [@MarcusStrube](https://discourse.mcneel.com/u/MarcusStrube)\
**Post date:** [March 16, 2017, 1:13pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/6 "2017-03-16T13:13:30Z")

</div>

With a box **selected** running this prints the value:

```
import rhinoscriptsyntax as rs
object = rs.GetObject(message=None, filter=0, preselect=True, select=True, subobjects=True)
x = rs.coercebrep(object)
x.UserDictionary.Set("Rolf", "rendered by RILLife") # <-- TM removed!
_, value = x.UserDictionary.TryGetValue('Rolf')
print(value)

```

For the most part I use Python only in GH, but you can read rhinoscript itself. I mean, the scripts. I think all coerceXXX() are in [utility.py](http://utility.py)

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 1:21pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/7 "2017-03-16T13:21:01Z")

</div>

> [@MarcusStrube](#):
>
> rs.coercebrep(object)

Ah, there we go! 10.000^10 thanks! You made my day.

RILThanks™!

// Rolf

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 2:33pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/8 "2017-03-16T14:33:51Z")

</div>

> [@RIL](#):
>
> UML?If there where a UML diagram somewhere explaining the basic concepts, that would…

… look something like this :

_Fig.1 Rhino.Geometry & Attributes & Brep (Updated). Now it looks messy with the `UserData` and `UserDictionary` classes… :_

 ![](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/d/f/df58a81e48b50cf8dd6b94361fea691cd7264a29.png)

// Rolf

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [March 16, 2017, 2:51pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/9 "2017-03-16T14:51:11Z")

</div>

Glad to see that you already found the answer 🙂

Anyway here is a very simple test script

```python
import Rhino
import rhinoscriptsyntax as rs

def main():
  gob = Rhino.Input.Custom.GetObject()
  gob.SetCommandPrompt( 'Object ?' )
  gob.Get()
  key = rs.GetString( 'Key ?' )
  val = rs.GetString( 'Value [Enter to read] ?' )
  rob = gob.Object( 0 ).Object()
  if val:
    rob.Attributes.SetUserString( key, val )
    print( 'Written value ' + val )
  else:
    val = rob.Attributes.GetUserString( key )
    print( 'Read value ' + val )

main()

```

I agree that what is missing AFAIK is a general explanation of what does what.

References that I know of are the samples here:

> **[Rhino and Grasshopper Developer Documentation](http://developer.rhino3d.com/)**
>
> Official developer resources for Rhino and Grasshopper. Rhino developer tools are royalty free and include support.

  
… and the rhinoscriptsyntax source copied on our PCs along with Rhino (very useful IMO)

If you allow a few quick (and maybe confused) words from a non-expert …  
Geometry is just that: theoretical geometrical objects  
Object and ObjRef refer to what sits in Rhino’s data base, representing the geometrical objects we see on the screen  
An Object contains a Geometry instance, but with RhinoCommon we can also work with Geometry instances (unlike rhinoscripsyntax, that can only reference Rhino Objects )

HTH

EDIT:  
Rhino’s data base that I mentioned earlier is here:  
[http://developer.rhino3d.com/api/RhinoCommonWin/html/N\_Rhino\_DocObjects\_Tables.htm](http://developer.rhino3d.com/api/RhinoCommonWin/html/N_Rhino_DocObjects_Tables.htm)  
I think these tables, mostly object tables, layer tables, etc are a good start point to understand how Rhino works … for scripting purposes, I mean

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [March 16, 2017, 2:58pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/10 "2017-03-16T14:58:22Z")

</div>

While there isn’t a UML diagram per say, you can look up the same data in the [RhinoCommon SDK](http://developer.rhino3d.com/api/RhinoCommonWin/html/N_Rhino.htm#!). See the[Brep class here.](http://developer.rhino3d.com/api/RhinoCommonWin/html/T_Rhino_Geometry_Brep.htm) You can inspect the inheritance tree, methods, properties etc there.

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 3:00pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/11 "2017-03-16T15:00:50Z")

</div>

> [@AndersDeleuran](#):
>
> You can inspect the inheritance tree, methods, properties etc there.

Yup, that’s exactly what I’m doing, adding some info to the UML diagram.

// Rolf

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [March 16, 2017, 3:26pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/12 "2017-03-16T15:26:53Z")

</div>

Then I’m a bit confused, is the Inheritance Hierarchy there not enough to answer your query? Edit: I see what you’re saying. Something that clarifies the relationships across classes. That would be cool, maybe you can automate this 😉

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 3:31pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/13 "2017-03-16T15:31:07Z")

</div>

@emilio, I think I got a good start from the example. I will from now on draw UML diagrams of my reading in the RhinoCommon SDK documentation. It is easier to get an overview when drawing. I draw only the most important feateures to start with, and this links and attributes I happen to use myself. Gradually the model will be more complete. It’s a good way of learning the structure.

What I find a bit confusing is the different import names for VBScript/.NET & PyhonScript. The names (scriptsyntax, …context etc).

It would be very helpful with a short-list with “equivalents” between all approaches, which would help resolve confusion while being a RILNewbie™ like me.

@AndersDeleuran: A diagram gives overview,. For a newbie a zillion class & attribute and package names criss cross on different pages doesn’t give a good overview very quickly. Over time everything eventually sinks in but…

**Edit 1** :

> [@AndersDeleuran](#):
>
> Something that clarifies the relationships across classes.

Yup. The UML diagram above makes it much easier to get an overview.

**Edit 2** :

> [@AndersDeleuran](#):
>
> That would be cool, maybe you can automate this 😉

Yes please, give me the sources and I’ll reverse engineer the whole thing (into [Enterprise Architect](http://www.sparxsystems.com/) which I used here) in a few minutes… 🙂

// Rolf

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [March 16, 2017, 7:43pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/14 "2017-03-16T19:43:18Z")

</div>

> [@RIL](#):
>
> What I find a bit confusing is the different import names for VBScript/.NET & PyhonScript. The names (scriptsyntax, …context etc).

Yes, these things aren’t so complex, just not easy to know for a newcomer.

scriptcontext is listed here:

> **[Where is scriptcontext DOCUMENTATION/MANUAL/CHM?](https://www.grasshopper3d.com/forum/topics/where-is-scriptcontext-documentation-manual-chm)**
>
> I'm moving a bit out of Grasshopper into pure Python scripting of Rhino, ignoring Rhinoscript in favor of Rhinocommon, but becoming more aware of scriptcontext…

And you can find it on your PC (just like rhinoscriptsyntax)

scriptcontext is often used in Python script to reach the RhinoDoc object that represents the Rhino document.  
You obtain the RhinoDoc object by scriptcontext.doc  
From this object you can get all Rhino tables: Objects, Layers, Views, etc.  
that you use to interact with the Rhino document: geometric objects, layers etc.

I think .NET and IronPython both use RhinoCommon, classes and members should be the same

scriptcontext is just a Python module that mimics VBScript’s RhinoScript methods using RhinoCommon.

Thus in IronPython you can freely mix RhinoCommon and rhinoscriptsyntax, along with .NET classes (e.g. System.Drawing.Color) and Python modules available in IronPython.

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 16, 2017, 8:42pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/15 "2017-03-16T20:42:50Z")

</div>

> [@emilio](#):
>
> You obtain the RhinoDoc object by scriptcontext.doc

Yes, I think I got it sorted out now. I’ve been drawing some more on the structure, and it gradually becomes clearer. Doing UML is a bit like code refactoring, useful for learning the code. Here another “thin” model (intended for overview) with some glitches which gradually will be plugged as I dig deeper into RhinoCommon :

Fig.1. Another RILCheatSheet™ :

 ![](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/8/c/8cfa6a583e293e39b6158692cdaa2bcad93bffd2.png)

// Rolf

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [March 17, 2017, 7:23am UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/16 "2017-03-17T07:23:32Z")

</div>

Nice work !  
Thanks for sharing.  
… trying to learn something about UML …

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 17, 2017, 8:32am UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/17 "2017-03-17T08:32:57Z")

</div>

The basics on UML diagrams should be covered in the following picture. Just differ **classes** from **object** instances (objects) like you differ a house drawing from an actual house (one drawing , many houses).

**Inheritance** uses fat arrowhead towards the parent. An arrow on other relations often mean “one way” (when the arrow is drawn). You seldom draw two-way arrows since it clutters the diagram without adding any essential info. The rolenames, like “Brep--------UserDictionary–\>” should be read “seen from the source class”, from the `Brep` or the `ObjectAttributes` in this case, so (a Brep object).UserDictionary will return the (instantiated) UserDictionary. Links that holds multiple instances (lists) should use plural form in the role names (and any of the these multiplicity symbols `*` or `n..*` or `1..*` if a least one instance must reside in the list, aso.

The names between “`< < > >`” are called \< \< stereotypes \> \> and may indicate different things (actually, whatever you designate, here I decided that the stereotypes display the Namespace)

 ![](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/6/7/675bfe3e40d94bebe79280710a158a3613e29498.png)

[details=Plug 🙂]Plug: I made a system once drawn in UML with many hundred classes which generated both the database structure and the code stubs, AND instantiated and injected the very diagram itself into the executable so as to provide runtime info about the model (a higher form of “reflection” actually). The architecture is still around and provides an industrial strength Model Driven Arcitecture (MDA) which is very (very) robust, no glitches. Links and attributes could be derived with simple text OCL-expressions, automagic subscriptions laid on all relations, etc, etc.

An updated C# version of that same system is called MDriven (I used the original Win32 Bold Architecture version of this, called Delphi 7 Architect once upon the time). This is the ultimate MDA system which atomagically autogenerates a basic UI for any system drawn as a UML class diagram, inlcuding statemachine generation from state diagrams. [http://www.new.capableobjects.com/products/eco-model-driven-framework/](http://www.new.capableobjects.com/products/eco-model-driven-framework/)

[![](http://www.new.capableobjects.com/wp-content/uploads/2011/02/EcoScreens.jpg) ](http://www.new.capableobjects.com/wp-content/uploads/2011/02/EcoScreens.jpg)

[/details]

// Rolf

---

<div class="post-metadata">

**Author:** ![emilio](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/emilio/32/771014_2.png) [@emilio](https://discourse.mcneel.com/u/emilio)\
**Post date:** [March 17, 2017, 10:36am UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/18 "2017-03-17T10:36:58Z")

</div>

Thanks a lot,Rolf !

---

<div class="post-metadata">

**Author:** ![RIL](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/ril/32/771758_2.png) [@RIL](https://discourse.mcneel.com/u/RIL)\
**Post date:** [March 17, 2017, 12:34pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/19 "2017-03-17T12:34:56Z")

</div>

My favorite example of interpreting UML class diagrams in the picture below.

**All about Types**  
Notice that the diagram shows two (2) ways to define “type”. The traditional Object Oriented (OO) Inheritance way (Male and Female classes descending from “Human”) and the more flexible GenderType-link to a, well, a GenderType (_more advanced both technically and conceptually because it also allows changing the gender, and to add any number of “genders”… 🙂_ ).

**Hierarchy**  
Anyway, since OOP involves “inheritance” I think that an example of Kind (Class Humans) as opposed to Generations (depicted by children & parents) helps the mind to find the best way to define different kinds of hierarchies.

**Interface** - The _Interface_ type is not included here, only Classes, Attributes and Relations, but _Interfaces_ are simply “injected” to classes with a pin symbol with a round pin head.

**Ownership Links** - Notice the difference between filled and unfilled _diamond_ symbols for certain relations :

- **Filled diamonds** (black) can be perceived as “owns” and code generators typically injects code to auto-create such related objects On Create of the owning class (and also destroyed together with the owning object)
- **Unfilled diamonds** can be perceived as “has”. A “has”-relation can be dropped, or reconfigured to refer to some other object instance as opposed to “owns” which live and die with the owner object.

**Configurable Type** - The “advanced” `GenderType` kind of type-concept (shown far below in the picture) is often used in other contexts, so never mind the concept of gender, it just goes well together with human inheritance and relations etc.

**Roles** - Notice also the direction from which you read the link-roles (“wife” is technically an attribute of Male and “husband” is an attribute of “Female” etc).

 ![](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/8/7/87ddd97c5ae1e3e1bd164fcf986f65b3ee3401a5.png)

There are a few more other UML notations not shown here, but this is the basic stuff that makes most sense for a start.

Edit: Notice also that using inheritance for defining Male & Female in software is _ **not** _ recommended (but for explaining the technical OO concept of inheritance it is useful). One reason for not using inheritance for gender is that the sequence of events for gaining the information may require that you create a “Person” or “Human” object first, and only after that you will learn about the gender, and so it’s more convenient to just create the Person class and assign the GenderType-link only when that info is known.

// Rolf

---

<div class="post-metadata">

**Author:** ![dharman](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dharman/32/482663_2.png) [@dharman](https://discourse.mcneel.com/u/dharman)\
**Post date:** [March 19, 2017, 12:01pm UTC](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267/20 "2017-03-19T12:01:46Z")

</div>

These diagrams are fantastic! If there is a way to have this as part of the documentation that would be awesome! 👍  
as you say: [quote=“RIL, post:13, topic:42267”]  
It’s a good way of learning the structure.  
[/quote]  
by the way It would be awesome if you could make the UML look like the grasshopper UI. Maybe @DavidRutten can help? 😉

[Next page](https://discourse.mcneel.com/t/how-access-userdictionary-in-python/42267.md?page=2)
