Python Forum
Python class members based on a type value
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python class members based on a type value
#1
Hi, I am curios whether it is possible to have a class define specific members based on a "type". I want to implement something like this:

enum type {
    REQUEST_A = 1,
    REQUEST_B = 2
};

struct packet {
    enum type type;
    union {
         struct a_args_s {
               int arg1;
         } a_args;
         struct b_args_s {
               int arg1;
               int arg2;
         } b_args;
     };
};
The enum type can be done with enum.IntEnum but I am not sure how to do the struct packet. I know it could be done with ctypes but I want to do with with pure Python.

I could think of something with the __setattr__() method, where only the correct attributes are allowed to be set but I was wondering if there was a better way?
Reply
#2
In Python I would create a base class and two subclasses
from abc import ABC

class Packet(ABC):
    pass

class APacket(Packet):
    def __init__(self, arg1: int):
        self.arg1 = arg1

class BPacket(Packet):
    def __init__(self, arg1: int, arg2: int):
        self.arg1 = arg1
        self.arg2 = arg2
« We can solve any problem by introducing an extra level of indirection »
Reply
#3
(Apr-07-2025, 04:54 PM)Gribouillis Wrote: In Python I would create a base class and two subclasses

Yes, I thought of that too. But that does not achieve the goal because you have *two* different classes, not one class that has different members like the struct.
Reply
#4
Could you elaborate in plain English what you want to achieve? For those not familiar with c++
I don't understand how "to have a class define specific members based on a "type"" relates to example. I see union of two methods with one/two arguments, but not different types (as I said, I am not familiar with c++)
As I understand it so far functools.singledispatchmethod() may be what you look for https://docs.python.org/3/library/functo...atchmethod
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
(Apr-07-2025, 05:38 PM)buran Wrote: Could you elaborate in plain English what you want to achieve? For those not familiar with c++
I don't understand how "to have a class define specific members based on a "type"" relates to example. I see union of two methods with one/two arguments, but not different types (as I said, I am not familiar with c++)
As I understand it so far functools.singledispatchmethod() may be what you look for https://docs.python.org/3/library/functo...atchmethod

The structure that I described can hold two different "packet" types. I can transfer the structure over a socket and on the receiving end decide what packet type it is based on the common type member. Based on that type member I know what other members are valid.

singledisplatchmethod is pretty close but it works on methods, not members.
Reply
#6
(Apr-07-2025, 05:05 PM)voidtrance Wrote: But that does not achieve the goal because you have *two* different classes, not one class that has different members like the struct.
The goal is far from clear. With my design, an instance of Packet can be either an instance of APacket or BPacket. You can still define functions that take Packet arguments and do whatever you want. You can also use polymorphism to implement methods that work transparently differently for APackets or BPackets.

Perhaps you could show us examples of how you want to use the type and why it would be better to have something that resembles a C union. The reason for the existence of C unions is mainly that C doesn't have classes and also that C structures are a very thin syntactic layer above the physical memory.
buran likes this post
« We can solve any problem by introducing an extra level of indirection »
Reply
#7
it looks like you try to write python code with C paradigm in mind and that is the problem

Maybe having two classes and singledispatch function on receiving end to process what you get would do..
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
If your interest is sending packets over a socket you should look at struct.

A literal interpretation of the C code.
import struct
from enum import IntEnum


class Request(IntEnum):
    REQUEST_A = 0
    REQUEST_B = 1


class Packet:
    
    def __init__(self, request: Request, arg1: int, arg2: int = 0) -> None:
        self.type = request
        self.arg1 = arg1
        self.arg2 = arg2

    def as_bytes(self):
        if self.type == Request.REQUEST_A:
            return struct.pack(">II", self.type, self.arg1)
        return struct.pack(">III", self.type, self.arg1, self.arg2)


print(Packet(Request.REQUEST_A, 42).as_bytes().hex())
print(Packet(Request.REQUEST_B, 42, 7).as_bytes().hex())
Output:
000000000000002a 000000010000002a00000007
If the only difference between the packet types is the number of arguments. I would do this:
import struct


class Packet:

    def __init__(self, *args) -> None:
        self.args = args

    def as_bytes(self):
        return struct.pack(f">I{len(self.args)}I", len(self.args), *self.args)


print(Packet(42).as_bytes().hex())
print(Packet(42, 7).as_bytes().hex())
Output:
000000010000002a 000000020000002a00000007
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Create a new subclass in a Python extension based on an existing class voidtrance 6 1,369 Mar-25-2025, 06:37 PM
Last Post: voidtrance
  Changing client.get() method type based on size of data... dl0dth 1 712 Jan-02-2025, 08:30 PM
Last Post: dl0dth
  associating members in a list to more than one features rezagholi 0 1,196 Mar-09-2023, 03:33 PM
Last Post: rezagholi
  Use a class type in it MathisDELAGE 2 1,767 Jan-29-2023, 11:37 AM
Last Post: MathisDELAGE
  search a list or tuple for a specific type ot class Skaperen 8 3,594 Jul-22-2022, 10:29 PM
Last Post: Skaperen
  Python generics: How to infer generic type from class attribute? Thoufak 0 3,775 Apr-25-2021, 09:31 AM
Last Post: Thoufak
  How to change 0 based indexing to 1 based indexing in python..?? Ruthra 2 5,926 Jan-22-2020, 05:13 PM
Last Post: Ruthra
  Type hinting - return type based on parameter micseydel 2 3,155 Jan-14-2020, 01:20 AM
Last Post: micseydel
  Object and type class Uchikago 2 2,833 Jul-28-2019, 10:35 AM
Last Post: DeaD_EyE
  How I can fill class members? AlekseyPython 0 2,055 Feb-14-2019, 06:32 AM
Last Post: AlekseyPython

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020