Ah great! Didn't think of that. Thanks! Yeah, once my current pull request is done (https://github.com/sympy/sympy/pull/2829) I might try to find some time to dig around with the metaclasses (I'm not the biggest fan of metaclasses in general - I usually find them quite confusing in practice)
Best regards /Björn On Wednesday, 29 January 2014 05:04:45 UTC+1, Aaron Meurer wrote: > > When you define a class inside a function, every time the function is > run, you get a new class, which will compare unequal to any previous > versions (the same thing is true when you define a function within a > function by the way). You could cache the class instances, but to me, > it seems easier to just set the option in the __init__ method of the > class. Something like > > class MaybeRealFunction(UndefinedFunction): > def __init__(self, *args, **kwargs): > self.real = kwargs.pop('real') > super(MaybeRealFunction, self).__init__(*args, **kwargs) > > @staticmethod > def _eval_is_real(self): > return self.real > > In [104]: r1 = MaybeRealFunction('f', real=False) > > In [105]: r2 = MaybeRealFunction('f', real=False) > > In [106]: r1(x) == r2(x) > Out[106]: True > > In [107]: r1(x).is_real > Out[107]: False > > But also note that: > > In [108]: r3 = MaybeRealFunction('f', real=True) > > In [109]: r2(x) == r3(x) > Out[109]: True > > If real is the only assumption you care about, you should just create > two separate classes, RealFunction and NotRealFunction. Otherwise, > you'll need override _hashable_content so that the hash (and therein > equality) comes out different. You noted that you are using them as > keys in dictionaries, so probably you do care about this. > > By the way, it would be nice if Function supported this directly, > i.e., Function('f', real=False). If you don't mind actually digging > into the metaclasses, a pull request would nice. > > Aaron Meurer > > > On Tue, Jan 28, 2014 at 10:16 AM, Björn Dahlgren > <bjo...@gmail.com<javascript:>> > wrote: > > Hello! > > > > I have an application where I use undefined functions as keys in > > dictionaries. > > > > This works great out of the box for sympy.Function > > However, I want to set real=True so I created a class factory which > > overrides _eval_is_real > > > > Now the trouble starts. I tried to work my way through the jungle of > > metaclasses and the assumptions systems > > but I don't seem to be able to fix this: > > > > -*- coding: utf-8 -*- > > > > from sympy.core.function import UndefinedFunction > > import sympy > > > > def MaybeRealFunction(key, real=None): > > > > class _Function(UndefinedFunction): > > @staticmethod > > def _eval_is_real(self): > > return real > > > > return _Function(key) > > > > > > def main(): > > x = sympy.Symbol('x') > > assert x == sympy.Symbol('x') > > > > f_x = sympy.Function('f')(x) > > assert f_x == sympy.Function('f')(x) > > > > g_x = MaybeRealFunction('g', real=True)(x) > > assert g_x.is_real > > assert g_x == g_x > > assert g_x == MaybeRealFunction('g', real=True)(x) # <--- This one > fails > > > > if __name__ == '__main__': > > main() > > > > > > Any ideas? > > > > Best regards, > > /Björn > > > > -- > > 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 sympy+un...@googlegroups.com <javascript:>. > > To post to this group, send email to sy...@googlegroups.com<javascript:>. > > > Visit this group at http://groups.google.com/group/sympy. > > For more options, visit https://groups.google.com/groups/opt_out. > -- 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 sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy. For more options, visit https://groups.google.com/groups/opt_out.