2014-11-10 2 views
0

Я пытаюсь создать объекты HasTraits, которые содержат несколько других экземпляров другого объекта HasTraits. Тем не менее, я всегда сталкиваюсь с проблемами при инициализации многих объектов HasTraits в главном объекте.Вложенные объекты HasTraits, как правильно инициализировать

Я привел простой пример, который дает ошибку. Может ли кто-нибудь объяснить лучший способ сделать это? -I никогда не знаю, когда я должен использовать черты.Instance (traits.Int) или просто traits.Int -Как передать исходные значения для признаков в конструкторе? Всякий раз, когда я делаю это я получаю ошибки как «тип INT требуется, но нашел тип traits.Int»

Спасибо за вашу помощь

import enthought.traits.api as traits 
import enthought.traits.ui.api as traitsui 

class Simple(traits.HasTraits): 

    minimum = traits.Int() 
    maximum= traits.Int() 
    ranged = traits.Range(minimum, maximum) 

    traits_view = traitsui.View(traitsui.Group(
    traitsui.Item('minimum'), 
    traitsui.Item('maximum'), 
    traitsui.Item('ranged')  
    )) 

class Complex(traits.HasTraits): 

    s1=Simple(minimum=1.0,maximum=5.0) 
    s2=Simple(minimum=2.0,maximum=10.0) 
    s3=Simple(minimum=traits.Int(1.0),maximum=traits.Int(5.0)) 

    traits_view = traitsui.View(traitsui.Group(
    traitsui.Item('s1'), 
    traitsui.Item('s2') 
    )) 

c= Complex() 
c.configure_traits() 
+0

У кого-нибудь есть идеи для этого? Спасибо – user2175850

+0

Представленный здесь код все равно не сможет представить читаемые результаты, даже если исходные черты. Решена проблема. Лучше всего уменьшить вопросы, заданные на этом форуме, по отдельным вопросам. Насколько я могу судить, вы сначала спрашиваете, как определить диапазон с помощью связанного признака в пределах одного объекта, определенного в классе Simple. Похоже, что с классовым комплексом возникает больше проблем, о которых поставленный вопрос не совсем подходит. Я отброшу свой ответ в отношении диапазона Range «range» ниже, но вы можете подумать о разделении вопросов, связанных с «Комплексом», на другой вопрос. – OYRM

ответ

1

Я тестировал код с теми же результатами, но, как я думаю о это, я понимаю, что есть проблема со средствами, которыми вы используете Range. Черты типа Range должны быть определены с минимальными и максимальными значениями, найденными в пределах trait_handlers.RangeType, что соответствует (int, long, float). Таким образом, вам нужно будет определить начальный диапазон с использованием этих типов, если вы не захотите заменить traits.api.BaseRange, что я не считаю разумным. Таким образом, вам придется придерживаться этих типов данных и выполнять немного более ручную работу, если вы хотите связать изменения с Simple.minimum и «Simple.maximum to the bounds of your Simple.ranged` trait.

Помните, что вы неверны, указав, что вы определяете значения Range в «Constructor». Определение переменных в теле класса не является конструктором. Ваша ранговая характеристика определяется с недопустимыми значениями, потому что вы пытаетесь передать объект «Черты», а не «int», «long» или «float». Даже если вы должны были преобразовать значение Int в значение int, имейте в виду, что вы работаете над определением класса в этот момент, а не значением экземпляра, поскольку класс еще не создан в той точке, в которой вы находитесь определяя значение Ranged. Имея это в виду, я добавил метод _init_ (read: Constructor) в класс Simple.

Я приспособил использование метода add_trait из Traits UI Manual

from traits.api import HasTraits, Int, Range 
from traitsui.api import View, Item 

class Simple(HasTraits): 
    minimum=Int() 
    maximum=Int() 
    ranged = Range(0, 0) 

traits_view = View(
     Item('minimum'), 
     Item('maximum'), 
     Item('ranged'), 
     resizable=True,width=600,height=400) 

    def __init__(self, minimum=0, maximum=0, **traits): 
     self.maximum = maximum 
     self.minimum = minimum 

     HasTraits.__init__(self, **traits) 
     ranged = Range(self.minimum, self.maximum) 
     self.remove_trait('ranged') 
     self.add_trait('ranged', ranged) 


    def _minimum_changed(self): 
     self.remove_trait("ranged") 
     ranged = Range(self.minimum, self.maximum) 
     self.add_trait('ranged', ranged) 


    def _maximum_changed(self): 
     self.remove_trait("ranged") 
     ranged = Range(self.minimum, self.maximum) 
     self.add_trait('ranged', ranged) 

c=Simple(minimum=1, maximum=5) 
c.configure_traits() 

Позвольте мне знать, если у вас есть какие-либо дополнительные вопросы.

EDIT: Я узнал, так что это может быть значительно упрощена

из traits.api импорта HasTraits, Int, Range

class Simple(HasTraits): 
    minimum=Int() 
    maximum=Int() 
    ranged = Range(low='minimum', high='maximum') 

используя строковые значения для низкого и высокого вызывает api, чтобы связать эти черты на заднем плане, выпекать во всем этом легком вкусе. Это, безусловно, более сжатая идиома, принятая для этой цели.

+0

Благодарим вас за этот ответ.Похоже, что для изменения диапазона характеристик Range вам действительно нужно удалить его, а затем добавить его снова? Я согласен, что здесь было больше вопросов. Мое основное недоумение - это 1) .Когда признак может рассматриваться как тип python, т. Е. Когда это признак. В то же время, что и int, и 2) почему мы определяем все черты в определении класса, а не в конструкторе __init__ , Я много использовал классы python, но я всегда определял все свои атрибуты в конструкторе, почему это отличается от Traits? Я могу задать это как отдельный вопрос, если вы предпочитаете. Спасибо – user2175850

+0

Я попытался ответить на вопрос «Как», но вопрос «Почему» - это совсем другое животное. Я бы предпочел, чтобы этот вопрос был опубликован независимо, чтобы дать некоторые из искусных архитектурных гуру пронести по нему. Я укажу вам в направлении моего понимания в любом случае 1) имеет отношение к тому, как создается экземпляр объекта «Черты» и аспекты мета-программирования признаков api. Вы можете прочитать traits.trait_handlers.TraitType source и http://docs.enthought.com/traits/traits_user_manual/custom.html, чтобы получить лучшую идею. – OYRM

+0

Что касается использования конструктора __init__, это то, что вы можете сделать, если хотите. Однако не редкость идиомы программирования делать объявления уровня класса до манипуляций уровня объекта, проведенных в коде экземпляра. Обсудить динамическую инициализацию Trait http://docs.enthought.com/traits/traits_user_manual/advanced.html#dynamic-initialization – OYRM

 Смежные вопросы

  • Нет связанных вопросов^_^