• Dynamic classes

    From Jonathan Gossage@3:633/280.2 to All on Tue May 20 01:51:53 2025
    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.


    --
    Jonathan Gossage

    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Stefan Ram@3:633/280.2 to All on Tue May 20 02: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!



    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: Stefan Ram (3:633/280.2@fidonet)
  • From Mats Wichmann@3:633/280.2 to All on Tue May 20 07: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)


    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Thomas Passin@3:633/280.2 to All on Tue May 20 08: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();





    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Rob Cliffe@3:633/280.2 to All on Tue May 20 08: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

    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Greg Ewing@3:633/280.2 to All on Tue May 20 10: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

    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Left Right@3:633/280.2 to All on Tue May 20 16:03:29 2025
    I have created a dynamic class using the type() function:
    x = type('MyFlags', (), {'Flag1': 1, 'Flag2': 2, 'Flag3: 4, ' '__init__' : __init__})

    I find that it's generally more convenient to do this using similar code:

    def constructor(flag1, flag2):
    class _Hidden:
    def __init__(self):
    self.flag1 = flag1
    self.flag2 = flag2
    return _Hidden()

    h = constructor('Flag1', 'Flag2')

    This accomplishes the same goal (with some overhead, perhaps), but is
    easier to format, the editor will recognize that you are writing a
    class rather than a bunch of data bits, you will have the ability to
    define the methods together with the class, benefit from the class initialization environment (eg. by using @static or @property
    decorators etc.). Also, this allows class parametrization in ways that
    are difficult to accomplish using metaclasses and other complicated
    mechanisms Python language provides to that end. Eg. you can
    conditionally inherit from different superclasses (so, you can use
    this approach as a factory that creates different classes), or you can conditionally add methods, conditionally provide different method
    bodies, conditionally provide different arguments to parametrized
    decorators.

    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: ---:- FTN<->UseNet Gate -:--- (3:633/280.2@fidonet)
  • From Stefan Ram@3:633/280.2 to All on Wed May 21 21: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,
    .. . .






    --- MBSE BBS v1.1.1 (Linux-x86_64)
    * Origin: Stefan Ram (3:633/280.2@fidonet)