4

I'd like something like below. Obviously it's invalid syntax, but is it possible to do something like this in python

def make_class(name):
    class name:
        def __init__(self):
            pass
    return name

make_class("Test")
a = Test()

NepNep
  • 274
  • 1
  • 2
  • 6
  • 4
    You need to use a technique called metaprogramming for this, which is almost always a bad idea. Are you *sure* this is exactly what you want to do? – ewhiting May 02 '20 at 20:44
  • 3
    Why do you need to do this? If you are just creating a class, why not just create a class? – GTBebbo May 02 '20 at 20:44
  • @GTBebbo, yeah I want to be able to create multiple classes with the same functionalities. The difference between them will be determined on parameters of the make_class function – NepNep May 02 '20 at 20:50
  • 1
    When you create an instance of a class you can pass in parameters to define its functionality – GTBebbo May 02 '20 at 20:51
  • Does this answer your question? [Dynamically creating classes - Python](https://stackoverflow.com/questions/3915024/dynamically-creating-classes-python)--see the second answer. – ggorlen May 02 '20 at 21:39
  • Just in case this is an x-z problem, please explain in your question *why* you want/need to do this? – DisappointedByUnaccountableMod May 02 '20 at 22:27
  • Please see [ask], [help/on-topic]. – AMC May 03 '20 at 01:09

3 Answers3

1

Defining a local class in your case seems useless. I'd do that if I did want to return it. There some disadvantages when defining local classes:

  • Readability: either the class is really trivial or the function inevitably grows quite long and its logic is lost in the class declaration. Also you have an extra level of indentation which might hurt readability if you have some nested loops somewhere
  • Performance: the class will be re-constructed at every function call. This usually wont take a huge amount of time, but it will cost a bit. If the function you are running is fast this cost may be significant.

There are also some advantages of defining a local class:

  • Locality: you are generally pretty sure that the class wont be used outside the function, in ways you didn't expect
  • Performance: looking up a local variable is significantly faster then looking up a global variable. If you create a big number of instances this might improve performance with respect to using a global class. However it's really really easy to counter this advantage via default arguments/local variables.

My suggestion would be to simply define the class globally and, if it should be private, use a name that starts with an underscore, like _MyClass, since this is the convention used to denote private items.

0

If you want to find a way of creating a new class without using class keyword, Python classes are instances of type classes. You can create a class by doing like this.

Person = type("Person", 
              (), 
              {
               "sayHello": lambda: "Hello there"})

You have Person class now with sayHello function defined beforehand.

If you really want to create your function, you can do like this. Actually this is a very bad way. You need to ask your question properly? What do you want to achive?

def create_class(class_name, superclass, namespace):
  return type(class_name, superclass, namespace)

Person = create_class("Person", 
              (), 
              {
               "sayHello": lambda: "Hello there"})

You can do something like this as well.

name = 'Operations'
body = """
def __init__(self, x, y):
    self.x = x
    self.y = y
def mul(self):
    return self.x * self.y
"""
bases = ()
namespace = {}
exec(body, globals(), namespace)
Operations = type(name, bases, namespace)
print(Operations)  # output: <class '__main__.Operations'>
instance = Operations(2, 5)
print(instance.mul())  # output: 10
0

You can define a class and define functions and such in its constuctor, no need to create a new class each time.

Below shows how you can pass in a variable value, a function and how that function can use the object's attributes and how it can be called from another function within the class itself. A lot of stuff, but hopefully by exploring it you will learn a lot!

class my_class:
    def __init__(self, name, cool_function):
        self.name = name
        self.my_function = cool_function

    def test(self):
        self.my_function(self)

def test_function(self):
    print(self.name)
    print("Hello World!")


a = my_class("Dave", test_function)
a.test()
# Prints "Dave" and "Hello World!"
GTBebbo
  • 1,198
  • 1
  • 8
  • 17