-2

I have a class with many member functions, and I want self.func to have function pointer based on provided name. However, this way each class should have a dict from all names to functions which is clearly a waste. Is there a better way to do it? The issue with using class variable (instead of member variable) is that some of those functions depend on the information from the instance.

class C:
    def __init__(func_name):
        name_to_func = {"f1": self.func1, "f100": self.func2}
        self.func = name_to_func[func_name]

    def func1(self): return 1
    def func100(self): return self.a

Using following method needs a different usage (c = C("f1"); c.func(c)) instead of (c = C("f1"); c.func()):

    class C:
        name_to_func = {"f1": C.func1, "f100": C.func2}
    def __init__(func_name):
        self.func = name_to_func[func_name]
Roy
  • 65
  • 2
  • 15
  • 40

2 Answers2

1

Static variables allow each Classes to have a single copy.

import random


class C:
    def __init__(self, func_name):
        self.func = lambda :C.name_to_func[func_name](self)
        self.a = random.random()

    def func1(self):
        return 1
    def func100(self):
        return self.a
    name_to_func = {"f1": func1, "f100": func100}

x = C("f1")
y = C("f100")
assert(x.name_to_func is y.name_to_func)
x.func()
y.func()

Do note that because name_to_func now needs to run at class definition time, we need to ensure that each function is defined before it and it can access it.

Edit I added the lambda to make it use an instance-specific variable. Is that what you were asking for.

Niteya Shah
  • 1,809
  • 1
  • 17
  • 30
  • The issue is that some of those functions depend on the information from the instance. – Roy Dec 09 '20 at 09:53
  • does other answer satisfy your requirements ? – Sekomer Dec 09 '20 at 11:37
  • @Roy can you give an example of your exact issue, because python is pretty dynamic and I don't see why the information from an instance cannot also be integrated. – Niteya Shah Dec 09 '20 at 13:55
0

Every attribute in Python stored in dictionaries, so it's not a 'clearly' waste.

This is how every class is created in Python

class name, inherited classes, attributes

type("", tuple(), dict())

so you can create classes or store your functions like that

def some_func(obj):
    return obj.attr

Foo = type(
     'Foo',
     (),
     {
         'attr': 100,
         'attr_val': lambda x : x.attr
         'my_func' : some_func
     }
)

Because of this implementation every attribute has O(1) time complexity

Check metaclasses from here

Sekomer
  • 688
  • 1
  • 6
  • 24