The most common interface for your class and .args do not have to be the same. .args just has to be one of the legal interfaces. Many classes store a .args that is different from what would usually be entered, for varying reasons. I think the most common is a canonicalization that would be more annoying for a user to enter but is more convenient to parse, but I suppose an equally legitimate reason would be to avoid computing something again.
I hope I understood your question correctly. Otherwise, a specific example might help. On Jun 25, 2012, at 6:41 AM, Sergiu Ivanov <[email protected]> wrote: > On Mon, Jun 25, 2012 at 2:53 PM, [email protected] > <[email protected]> wrote: >> Different parts of sympy have different assumptions about how strict >> the content of args should be. Focusing on the most important and what >> has not been questioned: >> >> If you have an instance called obj, this should hold: >> obj.func(*obj.args) == obj > > Thus, if I have MyClass derived from Basic, without overloading func, > I should have: > > MyClass obj; MyClass(obj.args) == obj > > which means that I should not allow private or internal data in .args. > Does that sound right? > > Then, how bad is it to use instance variables directly to store > internal data? > >> If you do funny stuff to your args, do not forget to check that >> _hashable_content was not brocken. >> >> It would be good to ensure that all the internal magic is not broken >> by your classes: >> >> for class Whatever and arguments test_args: >> >> hash(Whatever(*test_args)) = hash(Whatever(*test_args)). >> Whatever(*test_args) != Whatever(*different_args) > > I see; given the nature of my situation, it looks like this wouldn't > be broken if I chose to rely solely on .args. > >> Check that .subs, .atoms and .free_symbols work on expressions >> containing your classes (by expressions I do not necessary mean Expr >> subclasses). This reveals **a lot** of mistakes. > > Hm, that sounds like a nice test, in general, thank you. However, I'm > not sure the class I am currently working on can be a part of an > expression. subs and atoms should work in any case. I think free_symbols might only make sense for Expr, though. Aaron Meurer > >> Also keep in mind, that if you ever want to rebuild the expression >> tree with obj.func(*obj.args) it may be very bad if it takes a lot of >> time. > > Well, hopefully, the class I am talking about cannot really be made a > part of an expression tree. > > Yet, suppose MyClass(obj) does some sophisticated analysis of obj and > produces some internal data, fully depending on obj; and suppose that > it is bad to allow to construct MyClass directly from obj and that > internal data. This means that obj.func(*obj.args) is inevitably > going to take some time. How does one normally solve such problems? > >> Finally, correspondence between arguments of the constructor and the >> args attribute can be completely ignored (and there are some classes >> that do it), however it is a bit more difficult to reason about it, >> and it is not automatically supported by the sympy internal dark magic >> (by supported I again mean obj.func(*obj.args)==obj). > > I see. > > Thank you for your detailed explanation! > > Sergiu > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/sympy?hl=en. > -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
