Deutsch   English   Français   Italiano  
<100lqj6$33d8i$7@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: Lawrence D'Oliveiro <ldo@nz.invalid>
Newsgroups: comp.lang.python
Subject: Re: Dynamic classes (Posting On Python-List Prohibited)
Date: Thu, 22 May 2025 00:19:50 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 107
Message-ID: <100lqj6$33d8i$7@dont-email.me>
References: <mailman.67.1747767982.3008.python-list@python.org>
	<dynamic-20250521121804@ram.dialup.fu-berlin.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 22 May 2025 02:19:51 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="08c1197d0e2fbc8c5c93da80250c8ef4";
	logging-data="3257618"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/+CSv5selY1p2HySAYVGQE"
User-Agent: Pan/0.162 (Pokrosvk)
Cancel-Lock: sha1:fbeUNOiwN9biKvMjHpbMzuZ8XW0=

On 21 May 2025 11:20:55 GMT, Stefan Ram wrote:

> ... 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] ...

The main way I like to do it is start with a basic class object,
assign some basic attributes like __name__ and __doc__, and
dynamically attach additional members to it with setattr.

Here’s a partial example, taken from <https://gitlab.com/ldo/dbussy>.
Note the heavy use of lexical binding:

    class proxy(BusPeer.Object.ProxyInterface) :
        # class that will be constructed, to be instantiated for a given connection,
        # destination and path.

        # class field _iface_name contains interface name.
        __slots__ = ("_parent", "_conn", "_dest", "_path", "_timeout")

        def __init__(self, *, parent, connection, dest, path, timeout = DBUS.TIMEOUT_USE_DEFAULT) :
            if is_async :
                assert connection.loop != None, "no event loop to attach coroutines to"
            #end if
            self._parent = parent
            self._conn = connection
            self._dest = dest
            self._path = path
            self._timeout = timeout
        #end __init__

        # rest filled in dynamically below.

    #end proxy

    def def_method(intr_method) :
        # constructs a method-call method.

        if is_async :

            async def call_method(self, *args, **kwargs) :
                message = dbus.Message.new_method_call \
                  (
                    destination = self._dest,
                    path = dbus.unsplit_path(self._path),
                    iface = self._iface_name,
                    method = intr_method.name
                  )
                _append_args(message, intr_method, args, kwargs)
                if intr_method.expect_reply :
                    reply = await self._conn.send_await_reply(message, self._timeout)
                    result = reply.expect_return_objects(intr_method.out_signature)
                else :
                    message.no_reply = True
                    self._conn.send(message)
                    result = None
                #end if
                return \
                    result
            #end call_method

        else :

            def call_method(self, *args, **kwargs) :
                message = dbus.Message.new_method_call \
                  (
                    destination = self._dest,
                    path = dbus.unsplit_path(self._path),
                    iface = self._iface_name,
                    method = intr_method.name
                  )
                _append_args(message, intr_method, args, kwargs)
                if intr_method.expect_reply :
                    reply = self._conn.send_with_reply_and_block(message, self._timeout)
                    result = reply.expect_return_objects(intr_method.out_signature)
                else :
                    message.no_reply = True
                    self._conn.send(message)
                    result = None
                #end if
                return \
                    result
            #end call_method

        #end if

    #begin def_method
        call_method.__name__ = intr_method.name
        call_method.__doc__ = \
            (
                "method, %(args)s, %(result)s"
            %
                {
                    "args" :
                        (
                            lambda : "no args",
                            lambda : "args %s" % dbus.unparse_signature(intr_method.in_signature),
                        )[len(intr_method.in_signature) != 0](),
                    "result" :
                        (
                            lambda : "no result",
                            lambda : "result %s" % dbus.unparse_signature(intr_method.out_signature),
                        )[len(intr_method.out_signature) != 0](),
                }
            )
        setattr(proxy, intr_method.name, call_method)
    #end def_method