4

Here is an interactive Python session which uses components of the Enthought Tool Suite (ETS):

>>> import sys
>>> sys.version
'2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)]'
>>> import traits
>>> traits.__version__
'4.5.0'
>>> from traits.api import HasTraits, Range
>>> class Foo(HasTraits):
...     bar = Range (low=1, high=10)
...     
>>> foo = Foo()
>>> foo.bar
1
>>> foo.bar._low
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: 'int' object has no attribute '_low'

I would like to be able to access the predefined limits on the bar attribute of a Foo instance. How can this be done?

Thanks!

jim vickroy
  • 142
  • 2
  • 9

2 Answers2

2

Range() object has _low and _high attributes, which can be accessed. I suppose the underscore for them is used so that it does not shadow with low and high keyword parameters in Range().

>>> import traits.api
>>> bar = traits.api.Range(low=1, high=10)
>>> bar._low
1
>>> bar._high
10

Accessing them as a class instance attribute is still possible, however you need to know the name of the variable (in this base bar), so that you can access it in foo.traits(), which is a dictionary of all traits:

>>> foo = Foo()
>>> foo.traits()['bar'] # dictionary of all traits
<traits.traits.CTrait object at 0x000000000525A6D8>
>>> foo.traits()['bar'].trait_type
<traits.trait_types.Range object at 0x0000000005BA3EF0>
>>> foo.traits()['bar'].trait_type._low
1
>>> foo.traits()['bar'].trait_type._high
10
jermenkoo
  • 643
  • 5
  • 20
  • Sorry about the abbreviated comment; I'm a new poster and am having difficulty with the StackOverflow interface. My original question has been edited to emphasize that `bar` is a `class` instance attribute. Thanks for your interest! – jim vickroy Nov 13 '15 at 00:24
  • @jimvickroy: please see my updated answer, it took me a while to figure. Please accept my answer if you found it helpful, in order to mark the question as answered. (and we both get reputation) – jermenkoo Nov 13 '15 at 01:05
  • 1
    Wow! That is ugly! Not your answer ... but the procedure to do it :-) Thanks for figuring this out! I'm new to ETS Traits and find them very useful (except in situations like this). – jim vickroy Nov 13 '15 at 01:33
2

The standard way to do this would be to use low and high traits and assign them as the limits of the Range

from traits.api import HasTraits, Range, Int


class Foo(HasTraits):
    high = Int(10)
    low = Int(1)
    bar = Range(high='high', low='low')

You can assign the traits dynamically:

>>> f = Foo()
>>> f.bar = 5
>>> f.bar
5
>>> f.bar = 30
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/tim/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/traits/trait_types.py", line 1785, in _set
self.error( object, name, value )
  File "/Users/tim/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/traits/trait_handlers.py", line 172, in error value )
traits.trait_errors.TraitError: The 'bar' trait of a Foo instance must be 1 <= a number <= 10, but a value of 30 <type 'int'> was specified.
>>> f.high = 35
>>> f.bar = 30
>>> f.bar
30
Tim D
  • 1,645
  • 1
  • 25
  • 46