For most classes there isn't, but there can be. Using func instead of type() allows objects to have a function that isn't its literal Python class. This is necessary, for instance, if you want to allow the function to also be usable as an expression, since in that case it would also have to be a Python object (not a class).
An example of this are the predicate objects, like Q.positive. We want to be able to use both Q.positive and Q.positive(x) in logic expressions. If Q.positive were the type() of Q.positive(x), this would be impossible, because then Q.positive couldn't be an instance of Basic. So instead, it has its own type, and the .func is set appropriately: In [20]: type(Q.positive(x)) Out[20]: sympy.assumptions.assume.AppliedPredicate In [21]: Q.positive(x).func Out[21]: Q.positive Ideally we would like to do the same thing with functions as well (https://github.com/sympy/sympy/issues/4787) so that it will be possible to write things like cos + sin, and other "operator" like expressions. sin + cos may end up not being a good idea, but as the issue notes, something like D(f), where D is some kind of differential operator, would be possible in this case (right now it isn't really because f isn't an instance of Basic, so you can't just have D(f).args == (f,)). func has also been suggested as the way around issues with classes that want to put non-Basic things in their args (particularly strings, like with MatrixSymbol). Instead of MatrixSymbol('x', n, n).args == ('x', n, n) as it is now, which is bad and breaks a lot of things (because 'x' is not an instance of Basic), we would have MatrixSymbol('x', n, n).args == (n, n) and MatrixSymbol('x', n, n).func would be a special object that contains the 'x', which can recreate the original MatrixSymbol('x', n, n). Aaron Meurer On Mon, Nov 9, 2015 at 12:07 PM, Francesco Bonazzi <[email protected]> wrote: > By the way, is there a real difference between type(self)(*args) and > self.func(*args) ? > > On Monday, 9 November 2015 18:15:10 UTC+1, Aaron Meurer wrote: >> >> That's definitely a bug. Subclassing any class without changing >> anything shouldn't break anything. There are unfortunately several >> instances of this issue (see >> https://github.com/sympy/sympy/issues/6751). Probably somewhere in >> that code path something is referencing Add directly instead of using >> self.func, or doing a type comparison without using isinstance. >> >> Aaron Meurer >> >> On Mon, Nov 9, 2015 at 10:48 AM, Duane Nykamp <[email protected]> wrote: >> > OK, I'm pretty sure this is a bug. I don't have to change Add at all to >> > get >> > this infinite recursion, just create any subclass >> > >> > In [7]: Add(3,3,evaluate=False).evalf() >> > Out[7]: 6.00000000000000 >> > >> > In [8]: class Add2(Add): >> > ...: pass >> > ...: >> > >> > In [9]: Add2(3,3,evaluate=False).evalf() >> > RuntimeError: maximum recursion depth exceeded >> > >> > I can't figure out where the code is treating Add and its identical >> > subclass >> > Add2 differently. >> > >> > Duane >> > >> > -- >> > You received this message because you are subscribed to the Google >> > Groups >> > "sympy" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> > an >> > email to [email protected]. >> > To post to this group, send email to [email protected]. >> > Visit this group at http://groups.google.com/group/sympy. >> > To view this discussion on the web visit >> > >> > https://groups.google.com/d/msgid/sympy/60272dc0-8bf7-47db-83a9-01a840180943%40googlegroups.com. >> > >> > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/sympy. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/fe2324dd-75b8-4f14-a21b-f9fcb192b2c5%40googlegroups.com. > > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6JhaEiig4J0NqR4K%2Bi80Jn%2BYnzpbCBKb73y%3DLc_G4kX9w%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
