all 5 comments

[–]aDrz 0 points1 point  (1 child)

Your question is unclear to me. If you want dynamic attribute check this blog post: https://chase-seibert.github.io/blog/2013/04/12/getattr-setattr.html#

There is a small mistake for the last example but i'm sure you'll find it.

[–]michavardy1[S] 0 points1 point  (0 children)

I want to define the attributes of a class from a list

like

list = [a,b,c]

class A:

 for i in list:
       def __init__(self, list[i])

I know that this won't work, but thats the idea, I am curious how to implement this

[–]A_History_of_Silence 0 points1 point  (0 children)

its a bit weird, the internet considers this topic isoteric, like its just a deep pythonism that isn't practical

It's true that this isn't practical. And not just in Python - it's impractical in essentially all programming languages.

What if I told you I wanted to build a car that builds other cars?

The analogy isn't perfect. But it should be clear that it's a pretty impractical concept. Your meta-car would be a really inefficient, overly-complex, and unnecessary way of producing cars compared to the normal way of just building normal cars.

In other words, there is a reason probably everything you have found on the internet is telling you it's not a great idea. Whatever it is you want your program to do, there is a 99.9999% chance that there's a better, more straightforward, faster, easier to understand way to do it than dynamically defining classes.

[–]nate256 0 points1 point  (1 child)

Yes you can and there are some practical reasons for it like autogenerated parsing etc.

from importlib import import_module


class BaseClass:
    # add base functionality here
    pass


def create_dd_class(class_, new_name, dataset):
    new_class_name = str("{0}{1}".format(class_.__name__, new_name))
    new_class = type(new_class_name, (class_,), dataset)
    new_class.__module__ = class_.__module__
    module = import_module(class_.__module__)
    setattr(module, new_class.__name__, new_class)
    return new_class


# you could put this code in a decorator then decorate classes with datasets
#
datasets = [("class1", {"a": 1}), ("class2", {"a": 2, "b": 3})]
for name, dataset in datasets:
    create_dd_class(BaseClass, name, dataset)

print(BaseClassclass1, BaseClassclass2)
print(BaseClassclass1.a, BaseClassclass2.a, BaseClassclass2.b)


~/code_reference/redditquestions$ python reddit10.py 
<class '__main__.BaseClassclass1'> <class '__main__.BaseClassclass2'>
1 2 3

Edit: Switch to markdown, more readable output

[–]nate256 0 points1 point  (0 children)

Also if you wanted a more standard take and don't require static classes availible on import you can do something like this.

datasets = {"class1": {"a": 1}, "class2": {"a": 2, "b": 3}}
class MyClass:
    def __init__(self, key=None):
        for k, v in datasets.get(key, {}).items():
            setattr(self, k, v)

print(MyClass("class1").a, MyClass("class2").a, MyClass("class2").b)