ctypes.Structure subclasses let you define the same structure in Python, with a memory layout that could be memcpy-ed into via a memoryview. It's more typing, but it's also far less error-prone than long struct format strings.
Once defined, the memcpy equivalent in Python would be:
struct = MyStructure()
memoryview(struct).cast('B')[:] = mybytes
memoryview(struct) uses the buffer protocol to create a view of the underlying raw memory, .cast('B') returns a new view of the complicated structure as raw bytes, then [:] is used to slice assign from a bytes-like object.
There are also alternate constructors that can copy directly from a buffer if you have one available at construction time, e.g.:
struct = MyStructure.from_buffer_copy(mybytes)
or if mybytes is a mutable bytearray (or some other mutable bytes-like object) you can actually make a structure backed by it directly:
# struct is now backed by mybytearray; changing it will change mybytearray
struct = MyStructure.from_buffer(mybytearray)