traits weirdness

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

traits weirdness

Ross Harder
I don't understand how to mix Traits and regular python attributes in
a single class

###########################################################################
for this:
from enthought.traits.api import HasTraits, Float

class CoordSystem(HasTraits):

        wavelength = Float(1.0)
        dQdpx = 4.0

if __name__=="__main__":

  coord=CoordSystem()
  print coord.traits()

I get the expected output where dQdpx is not a trait.
{'trait_added': <enthought.traits.traits.CTrait object at 0x716088>,
'wavelength': <enthought.traits.traits.CTrait object at 0x653c90>,
'trait_modified': <enthought.traits.traits.CTrait object at 0x73afa8>}

########################################################################
But for this:
from enthought.traits.api import HasTraits, Float

class CoordSystem(HasTraits):

        wavelength = Float(1.0)

        def __init__(self, **traits):
                super(CoordSystem, self).__init__(**traits)
                self.dQdpx = 4.0

if __name__=="__main__":

  coord=CoordSystem()
  print coord.traits()

I get output that indicates that dQdpx is a trait... It will also show
up in configure_traits()
{'trait_added': <enthought.traits.traits.CTrait object at 0x716088>,
'wavelength': <enthought.traits.traits.CTrait object at 0x653c90>,
'trait_modified': <enthought.traits.traits.CTrait object at 0x73afa8>,
'dQdpx': <enthought.traits.traits.CTrait object at 0x716348>}
##############################################################################################


This a really frustrating and there doesn't seem to be anything in the
docs or tutorials regarding it.


Thanks,
ROss
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Robert Kern
On Thu, Apr 1, 2010 at 8:24 PM, Ross Harder <[hidden email]> wrote:

> I don't understand how to mix Traits and regular python attributes in
> a single class
>
> ###########################################################################
> for this:
> from enthought.traits.api import HasTraits, Float
>
> class CoordSystem(HasTraits):
>
>        wavelength = Float(1.0)
>        dQdpx = 4.0
>
> if __name__=="__main__":
>
>  coord=CoordSystem()
>  print coord.traits()
>
> I get the expected output where dQdpx is not a trait.
> {'trait_added': <enthought.traits.traits.CTrait object at 0x716088>,
> 'wavelength': <enthought.traits.traits.CTrait object at 0x653c90>,
> 'trait_modified': <enthought.traits.traits.CTrait object at 0x73afa8>}
>
> ########################################################################
> But for this:
> from enthought.traits.api import HasTraits, Float
>
> class CoordSystem(HasTraits):
>
>        wavelength = Float(1.0)
>
>        def __init__(self, **traits):
>                super(CoordSystem, self).__init__(**traits)
>                self.dQdpx = 4.0
>
> if __name__=="__main__":
>
>  coord=CoordSystem()
>  print coord.traits()
>
> I get output that indicates that dQdpx is a trait... It will also show
> up in configure_traits()
> {'trait_added': <enthought.traits.traits.CTrait object at 0x716088>,
> 'wavelength': <enthought.traits.traits.CTrait object at 0x653c90>,
> 'trait_modified': <enthought.traits.traits.CTrait object at 0x73afa8>,
> 'dQdpx': <enthought.traits.traits.CTrait object at 0x716348>}
> ##############################################################################################
>
>
> This a really frustrating and there doesn't seem to be anything in the
> docs or tutorials regarding it.

Assigning an attribute to an instance will create a trait on the fly.
In the former case, however, you just assigned an attribute to the
class itself. No trait is created. The attribute only appears on the
instance because of the normal attribute lookup rules. It's not
covered much in the docs or tutorials because it's not really
something you should do.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Ross Harder
I'm sorry but I really don't understand.
I don't want dQdpx to be a trait.  It seems that it is a trait for some reason.
What should I not do?  I don't understand why dQdpx appears in the
configure_traits() UI if it is not a trait.

In principle I don't want dQdpx to be 4.0, I actually want it to be
computed from the wavelength trait and have it changed in the
_wavelength_changed() function.

Thanks for the quick response,
Ross



> Assigning an attribute to an instance will create a trait on the fly.
> In the former case, however, you just assigned an attribute to the
> class itself. No trait is created. The attribute only appears on the
> instance because of the normal attribute lookup rules. It's not
> covered much in the docs or tutorials because it's not really
> something you should do.
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless
> enigma that is made terrible by our own mad attempt to interpret it as
> though it had an underlying truth."
>  -- Umberto Eco
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Didrik Pinte-2
On Thu, 2010-04-01 at 23:36 -0500, Ross Harder wrote:
> I'm sorry but I really don't understand.
> I don't want dQdpx to be a trait.  It seems that it is a trait for some reason.
> What should I not do?  I don't understand why dQdpx appears in the
> configure_traits() UI if it is not a trait.

It is a trait as explained by Robert (because you assigned the attribute
on the instance, it does create a trait on the fly !)


> In principle I don't want dQdpx to be 4.0, I actually want it to be
> computed from the wavelength trait and have it changed in the
> _wavelength_changed() function.

You could then define dQdpx as a Property depending on the wavelength

Something like :

from enthought.traits.api import HasTraits, Float, Property

class CoordSystem(HasTraits):

    wavelength = Float(1.0)
    dQdpx = Property(Float, depends_on="wavelength")

    def _get_dQdpx(self):
        return self.wavelength * 4.0

if __name__=="__main__":

  coord=CoordSystem()
  print coord.traits()


And if you want to hide the dQdpx value from the view, just define a
view that does not show it :

from enthought.traits.ui.api import View, Item
from enthought.traits.api import HasTraits, Float, Property

class CoordSystem(HasTraits):

    wavelength = Float(1.0)
    dQdpx = Property(Float, depends_on="wavelength")

    def _get_dQdpx(self):
        return self.wavelength * 4.0

   traits_view = View(Item("wavelength"))


if __name__=="__main__":

  coord=CoordSystem()
  print coord.traits()
  coord.configure_traits()


-- Didrik

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Ross Harder
Sorry for being a bother, but it really seems to me that it is
impossible to mix traits and standard attributes.  This did not work
either:

from enthought.traits.api import HasTraits, Float

class CoordSystem(HasTraits):

        wavelength = Float(1.0)
        dQdpx=0.0

        def __init__(self, **traits):
                super(CoordSystem, self).__init__(**traits)
                self.dQdpx = 4.0

if __name__=="__main__":

  coord=CoordSystem()
  print coord.traits()


gives this output:
{'trait_added': <enthought.traits.traits.CTrait object at 0x716088>,
'wavelength': <enthought.traits.traits.CTrait object at 0x653c90>,
'trait_modified': <enthought.traits.traits.CTrait object at 0x73afa8>,
'dQdpx': <enthought.traits.traits.CTrait object at 0x716348>}

How am I supposed to do it?

Thanks,
Ross


On Fri, Apr 2, 2010 at 7:34 AM, Didrik Pinte <[hidden email]> wrote:

> On Thu, 2010-04-01 at 23:36 -0500, Ross Harder wrote:
>> I'm sorry but I really don't understand.
>> I don't want dQdpx to be a trait.  It seems that it is a trait for some reason.
>> What should I not do?  I don't understand why dQdpx appears in the
>> configure_traits() UI if it is not a trait.
>
> It is a trait as explained by Robert (because you assigned the attribute
> on the instance, it does create a trait on the fly !)
>
>
>> In principle I don't want dQdpx to be 4.0, I actually want it to be
>> computed from the wavelength trait and have it changed in the
>> _wavelength_changed() function.
>
> You could then define dQdpx as a Property depending on the wavelength
>
> Something like :
>
> from enthought.traits.api import HasTraits, Float, Property
>
> class CoordSystem(HasTraits):
>
>    wavelength = Float(1.0)
>    dQdpx = Property(Float, depends_on="wavelength")
>
>    def _get_dQdpx(self):
>        return self.wavelength * 4.0
>
> if __name__=="__main__":
>
>  coord=CoordSystem()
>  print coord.traits()
>
>
> And if you want to hide the dQdpx value from the view, just define a
> view that does not show it :
>
> from enthought.traits.ui.api import View, Item
> from enthought.traits.api import HasTraits, Float, Property
>
> class CoordSystem(HasTraits):
>
>    wavelength = Float(1.0)
>    dQdpx = Property(Float, depends_on="wavelength")
>
>    def _get_dQdpx(self):
>        return self.wavelength * 4.0
>
>   traits_view = View(Item("wavelength"))
>
>
> if __name__=="__main__":
>
>  coord=CoordSystem()
>  print coord.traits()
>  coord.configure_traits()
>
>
> -- Didrik
>
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Robert Kern
On Fri, Apr 2, 2010 at 10:56 AM, Ross Harder <[hidden email]> wrote:
> Sorry for being a bother, but it really seems to me that it is
> impossible to mix traits and standard attributes.

Basically, yes. Why do you want to? What is your use case that
requires that you have a regular attribute and forbids a trait?

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Ross Harder
I guess it's just a matter of not understanding what's going on.   If
I'm investing time in writing something I like to know what is going
on.
The documentation introduction says:
"A class can freely mix trait-based attributes with normal Python
attributes, or can opt to allow the use of only a fixed or open set of
trait attributes within the class."

There seem to be a lot of caveats to "freely".

Like I said, I'm just trying to understand what traitified python is
like.  If something gets traitified without my explicit knowlege, how
do I know that there won't be some datatype information imposed
without my knowledge?

It's a basic hesitancy to jump ship from C, where I feel in control,
and take advantage of the beauty of traited python, where I don't have
a deep understanding of any of it.

For now I'll customize the View and keep going.  Hopefully I'll fall
in love with traits.

Ross








On Fri, Apr 2, 2010 at 12:05 PM, Robert Kern <[hidden email]> wrote:

> On Fri, Apr 2, 2010 at 10:56 AM, Ross Harder <[hidden email]> wrote:
>> Sorry for being a bother, but it really seems to me that it is
>> impossible to mix traits and standard attributes.
>
> Basically, yes. Why do you want to? What is your use case that
> requires that you have a regular attribute and forbids a trait?
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless
> enigma that is made terrible by our own mad attempt to interpret it as
> though it had an underlying truth."
>  -- Umberto Eco
> _______________________________________________
> Enthought-Dev mailing list
> [hidden email]
> https://mail.enthought.com/mailman/listinfo/enthought-dev
>
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Robert Kern
On Fri, Apr 2, 2010 at 12:28 PM, Ross Harder <[hidden email]> wrote:
> I guess it's just a matter of not understanding what's going on.   If
> I'm investing time in writing something I like to know what is going
> on.
> The documentation introduction says:
> "A class can freely mix trait-based attributes with normal Python
> attributes, or can opt to allow the use of only a fixed or open set of
> trait attributes within the class."
>
> There seem to be a lot of caveats to "freely".

It's a bit of a lie, actually. The author meant that you can mix
declared traits and undeclared attributes freely. Under the covers,
though, a trait will be created for the newly assigned attribute. That
trait follows Python semantics, though.

> Like I said, I'm just trying to understand what traitified python is
> like.  If something gets traitified without my explicit knowlege, how
> do I know that there won't be some datatype information imposed
> without my knowledge?

It won't. I guarantee it. What datatype information could we impose?
You can check for yourself, though:

In [1]: from enthought.traits.api import *

In [2]: class A(HasTraits):
   ...:     pass
   ...:

In [3]: a = A()

In [4]: a.x = 1

In [5]: a.trait('x')
Out[5]: <enthought.traits.traits.CTrait at 0x17f2240>

In [6]: ct = _

In [7]: ct.trait_type
Out[7]: <enthought.traits.trait_types.Python at 0x1821b30>

In [9]: p = ct.trait_type

In [10]: p??
Type:             Python
Base Class:       <class 'enthought.traits.trait_types.Python'>
String Form:   <enthought.traits.trait_types.Python object at 0x1821b30>
Namespace:        Interactive
File:             /Users/rkern/svn/et/Traits/enthought/traits/trait_types.py
Source:
class Python ( TraitType ):
    """ Defines a trait that provides behavior identical to a standard Python
        attribute. That is, it allows any value to be assigned, and raises an
        ValueError if an attempt is made to get the value before one has been
        assigned. It has no default value. This trait is most often used in
        conjunction with wildcard naming. See the *Traits User Manual* for
        details on wildcards.
    """

    # The standard metadata for the trait:
    metadata = { 'type': 'python' }

    # The default value for the trait:
    default_value = Undefined
Constructor Docstring:
    This constructor method is the only method normally called
    directly by client code. It defines the trait. The
    default implementation accepts an optional, untype-checked default
    value, and caller-supplied trait metadata. Override this method
    whenever a different method signature or a type-checked
    default value is needed.
Call def: p(self, *args, **kw)

Call docstring:
    Allows a derivative trait to be defined from this one.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: traits weirdness

Gary Pajer
In reply to this post by Ross Harder
On Fri, Apr 2, 2010 at 2:28 PM, Ross Harder <[hidden email]> wrote:
I guess it's just a matter of not understanding what's going on.   If
I'm investing time in writing something I like to know what is going
on.
The documentation introduction says:
"A class can freely mix trait-based attributes with normal Python
attributes, or can opt to allow the use of only a fixed or open set of
trait attributes within the class."

There seem to be a lot of caveats to "freely".

The behavior you found is also a surprise to me, also because I read that paragraph at some time in the past.  I've never had a problem, or a reason to want otherwise.  But I thought I could mix traits and non-traits if I wanted to (reasons unknown).  I can think of one small case when it makes a difference: using  foo.configure_traits() with no explicit view defined.  You'll get all the properties, traits and "non-traits".   All things considered, I don't think it's an issue for me now that I'm aware of it.

-gary

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev