-1

I would like to have a function that allows generating classes with custom class attributes. Like so:

def test_factory(a):
    class Test:
        a = a
    return Test

However, when I try to call test_factory, I get an error:

test_factory(1)
> NameError: name 'a' is not defined

The expected behaviour would be:

t1 = test_factory(1)
t2 = test_factory(2)
print(t1.a, t2.a)
> 1, 2

How can I create classes that differ in their class attributes by calling a function?

4
  • 1
    Seems like you're coming from JS. More pythonic way would be to use a dictionary Commented Apr 27, 2020 at 13:46
  • 1
    there is this link I found. It might be worth a read Commented Apr 27, 2020 at 13:50
  • Note that you would get a similar error if Test were a function instead of a class. Name resolution rules in Python cause every assignment to imply the variable is local to that block. Commented Apr 27, 2020 at 14:08
  • @MaxxikCZ thanks - that link indeed was worth a read. Commented Apr 27, 2020 at 18:00

2 Answers 2

2

You have to rename the function argument to not collide with the name of the class attribute:

def test_factory(b):
    class Test:
        a = b
    return Test

>>> t1 = test_factory(1)
>>> t2 = test_factory(2)
>>> print(t1.a, t2.a)
1 2
Sign up to request clarification or add additional context in comments.

Comments

1

When parsing the class statement, the assignment to a defines it as part of the temporary class namespace, similar to an assignment to a local variable in a function definition. As such, the name a then shadows the name of the parameter in the enclosing function scope.

You can either change the parameter name (as shown by schwobaseggl)

def test_factory(a_value):
    class Test:
        a = a_value
    return Test

or set the attribute after the definition:

def test_factory(a):
    class Test:
        pass
    Test.a = a
    return Test

or call type directly:

def test_factory(a):
    return type('Test', (), {'a': a})

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.