• Re: Dynamic classes

    From Stefan Ram@21:1/5 to Jonathan Gossage on Mon May 19 16:33:21 2025
    Jonathan Gossage <jgossage@gmail.com> wrote or quoted:
    I have created a dynamic class using the type() function:
    x = type('MyFlags', (), {'Flag1': 1, 'Flag2': 2, 'Flag3: 4, ' '__init__' : >__init__})
    The new class is there, and the class variables, Flag1, Flag2, and Flag3,
    are present correctly. However, when I try to create an instance of this >class with the following code:
    y = x('Flag1', 'Flag2')
    it fails with a TypeError stating that 'MyFlags' does not accept arguments. >What do I have to do to make this happen?. BTW __init__(self, *args) is >defined as the instance initializer.

    Excellent question! So, the reason you're getting that
    TypeError is your __init__ function isn't actually hooked up
    right when you build your class with "type". You got to set up
    your init before you call "type", and then drop it into the
    class dictionary as a /function/ (not as a string). Also, looks
    like you've got a typo in the Flag3 line - missing a quote.

    Here's how you want to do it:

    def __init__(self, *args):
    self.flags = args

    x = type(
    'MyFlags',
    (),
    {
    'Flag1': 1,
    'Flag2': 2,
    'Flag3': 4,
    '__init__': __init__
    }
    )

    y = x('Flag1', 'Flag2')

    print(y.flags) # Output: ('Flag1', 'Flag2')

    Basically, "type" needs the actual function object for
    "__init__", not just the name. If you mess that up or have
    a typo, Python just falls back on the default init, which doesn't
    take any arguments, and that's why you get the error.

    Here's the rundown:

    Problem: "__init__" isn't set up right
    Fix: Define "__init__" before calling "type"

    Problem: Typo in your dict
    Fix: Make sure it's 'Flag3': 4

    Problem: Wrong reference
    Fix: Pass the function, not a string

    Once you clean that up, your class should take arguments just fine!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mats Wichmann@21:1/5 to Jonathan Gossage via Python-list on Mon May 19 15:49:53 2025
    On 5/19/25 09:51, Jonathan Gossage via Python-list wrote:
    I have created a dynamic class using the type() function:
    x = type('MyFlags', (), {'Flag1': 1, 'Flag2': 2, 'Flag3: 4, ' '__init__' : __init__})
    The new class is there, and the class variables, Flag1, Flag2, and Flag3,
    are present correctly. However, when I try to create an instance of this class with the following code:
    y = x('Flag1', 'Flag2')
    it fails with a TypeError stating that 'MyFlags' does not accept arguments. What do I have to do to make this happen?. BTW __init__(self, *args) is defined as the instance initializer.

    Might help if you show the init function. I've done something similar to
    this without trouble, but not using the unpacking (i.e. *args). I used
    this in an ancient blog post (thus, pre-typing, and such):

    def transact(acct, amount):
    acct.balance += amount

    def pay_interest(acct):
    acct.balance += acct.balance * acct.interest_rate

    def account_init(acct, num, name, bal, rate):
    acct.acct_number = num
    acct.acct_holder = name
    acct.balance = bal
    acct.interest_rate = rate

    account = {
    "acct_number": "XXX",
    "acct_holder": "",
    "balance": 0.0,
    "interest_rate": 0.0,
    "transact": transact,
    "pay_interest": pay_interest,
    "__init__": account_init,
    }

    AccountType = type("AccountType", (), account)

    myaccount = AccountType("1234567", "J. Q. Public", 20.0, 0.01) print(myaccount.balance)
    myaccount.transact(-10)
    print(myaccount.balance)
    myaccount.pay_interest()
    print(myaccount.balance)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Mats Wichmann via Python-list on Mon May 19 18:11:20 2025
    On 5/19/2025 5:49 PM, Mats Wichmann via Python-list wrote:
    On 5/19/25 09:51, Jonathan Gossage via Python-list wrote:
    I have created a dynamic class using the type() function:
    x = type('MyFlags', (), {'Flag1': 1, 'Flag2': 2, 'Flag3: 4, '
    '__init__' :
    __init__})
    The new class is there, and the class variables, Flag1, Flag2, and Flag3,
    are present correctly. However, when I try to create an instance of this
    class with the following code:
    y = x('Flag1', 'Flag2')
    it fails with a TypeError stating that 'MyFlags' does not accept
    arguments.
    What do I have to do to make this happen?. BTW __init__(self, *args) is
    defined as the instance initializer.

    Might help if you show the init function. I've done something similar to
    this without trouble, but not using the unpacking (i.e. *args). I used
    this in an ancient blog post (thus, pre-typing, and such):

    def transact(acct, amount):
        acct.balance += amount

    def pay_interest(acct):
        acct.balance += acct.balance * acct.interest_rate

    def account_init(acct, num, name, bal, rate):
        acct.acct_number = num
        acct.acct_holder = name
        acct.balance = bal
        acct.interest_rate = rate

    account = {
        "acct_number": "XXX",
        "acct_holder": "",
        "balance": 0.0,
        "interest_rate": 0.0,
        "transact": transact,
        "pay_interest": pay_interest,
        "__init__": account_init,
    }

    AccountType = type("AccountType", (), account)

    myaccount = AccountType("1234567", "J. Q. Public", 20.0, 0.01) print(myaccount.balance)
    myaccount.transact(-10)
    print(myaccount.balance)
    myaccount.pay_interest()
    print(myaccount.balance)


    It's interesting that in Jython there is a way to do something
    conceptually similar to turn a Jython class into a Java class. Here's
    one of mine:

    synchronized CoordinatorType getCoord() {
    JythonObjectFactory factory = new JythonObjectFactory (
    // Type class, Jython module name, class name
    CoordinatorType.class, "Coordinator", "Coordinator");

    // Java class
    CoordinatorType coord = (CoordinatorType) factory.createObject();
    return coord;
    }

    // Instantiate a Coordinator
    // Error handling elided for clarity
    CoordinatorType c;
    c = getCoord();

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rob Cliffe@21:1/5 to Thomas Passin via Python-list on Mon May 19 23:29:56 2025
    On 19/05/2025 23:11, Thomas Passin via Python-list wrote:
    On 5/19/2025 5:49 PM, Mats Wichmann via Python-list wrote:
    On 5/19/25 09:51, Jonathan Gossage via Python-list wrote:
    I have created a dynamic class using the type() function:
    x = type('MyFlags', (), {'Flag1': 1, 'Flag2': 2, 'Flag3: 4, '
    '__init__' :
    __init__})
    This is not my area of expertise, but there is a misplaced quote before
        '__init__'
    that should be after
        'Flags3
    Correct this, and your example runs without error.
    Best wishes
    Rob Cliffe

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Greg Ewing@21:1/5 to Stefan Ram on Tue May 20 12:29:09 2025
    On 20/05/25 4:33 am, Stefan Ram wrote:
    So, the reason you're getting that
    TypeError is your __init__ function isn't actually hooked up
    right when you build your class with "type". You got to set up
    your init before you call "type", and then drop it into the
    class dictionary as a /function/ (not as a string).

    That's what he did, or at least that's what he tried to do.
    It turns out the misplaced quote was the entire problem -- by a
    fluke, it didn't result in a syntax error, and ended up putting
    the __init__ function into the dict under the name
    'Flag3: 4, __init__'.

    --
    Greg

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Left Right on Wed May 21 11:20:55 2025
    Left Right <olegsivokon@gmail.com> wrote or quoted:
    I find that it's generally more convenient to do this using similar code:
    def constructor(flag1, flag2):
    class _Hidden:

    That tracks, but I have this setup where I lay out a table to
    map out my markup language [1] and then use some dynamic code
    to spin up the classes based on that table [0], and I am not
    really sure how your way would fit in with that.

    [0]

    globals_dict = globals()
    for name, props in element_properties.items():
    cls = type(name.capitalize(), (Element,), {'element_properties': props})
    globals_dict[name.capitalize()] = cls

    [1]

    element_properties = {
    'title': {
    'level': IS_BLOCK,
    'contents': CANT_CONTAIN_ELEMENTS,
    'open_tag': None,
    'close_tag': None,
    'use_check': False,
    },
    'author': {
    'level': IS_BLOCK,
    'contents': CANT_CONTAIN_ELEMENTS,
    'open_tag': None,
    'close_tag': None,
    'use_check': False,
    },
    'language': {
    'level': IS_BLOCK,
    'contents': CANT_CONTAIN_ELEMENTS,
    'open_tag': None,
    'close_tag': None,
    'use_check': False,
    },
    'h1': {
    'level': IS_BLOCK,
    'contents': CAN_CONTAIN_ELEMENTS,
    'open_tag': '<h1>',
    'close_tag': '</h1>',
    'use_check': True,
    },
    'toc': {
    'level': IS_BLOCK,
    'contents': CANT_CONTAIN_ELEMENTS,
    'open_tag': None,
    'close_tag': None,
    'use_check': False,
    },
    'head': {
    'level': IS_BLOCK,
    'contents': CANT_CONTAIN_ELEMENTS,
    'open_tag': None,
    'close_tag': None,
    'use_check': False,
    },
    'par': {
    'level': IS_BLOCK,
    . . .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)