Với python có cấu trúc tương tự như tạo Struct không?

Em học năm hai, học lập trình C và sử dụng nó để học môn cấu trúc dữ liệu và giải thuật. Cô em dạy môn này thì lại cho sinh viên code bằng python, đa phần bọn em chưa bắt nhịp được vì là ngôn ngữ mới. Trong một bài tập lớn ctdl-gt, có phần bài làm mà nếu em code bằng C thì xử lý bằng mảng, trong đó các phần tử trong mảng được khai báo bằng kiểu Struct do mình lập. Vậy cho em hỏi với python có cấu trúc tương tự như tạo Struct cho các thành phần a[i] trong mảng một chiều như C không ạ. Em rất cần, vì mới chạm vào ngôn ngữ python được vài ngày, chưa thể nắm được ngôn ngữ này. Em cảm ơn ạ.
ví dụ: trong code C

struct du_lieu
{
	char ten[30];
	float so;
}a[3];
void nhap()
{
	
	for(int i=0;i<3;i++)
	{
		printf("Nhap vao ten hang muc:"); fflush(stdin);
		gets(a[i].ten);
		printf("Nhap vao so lieu:"); fflush(stdin); 
		scanf("%f",&a[i].so);
	}
}

Python có một cái gọi là namedtuple, có vẻ giống struct (vì có thể gọi được attribute) nhưng về bản chất vẫn là tuple:

Returns a new tuple subclass named typename

Ngoài cái gọi được tên attribute ra thì chẳng có gì giống struct của C cả.

from collections import namedtuple

Something = namedtuple("Something", ["x", "y"])
p1 = Point(1, 2)
print(p1)
# gọi attribute
print(p1.x, p1.y)
# gọi theo chỉ số
print(p1[0], p1[1])

# nếu có ý định gán thì error ngay lập tức
p1.x = 2  # lỗi AttributeError: can't set attribute

Thay vì dùng struct như vậy, Python ưu tiên tạo class object hơn (bonus: struct trong C++ không khác gì class).

class Something:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p2 = Something(1, [1, 2, 3])
p2.x = 3  # gán được
4 Likes

ồ cảm ơn anh, rất chật vật khi giảng viên dùng ngôn ngữ mới với mình để minh họa code anh ạ

Nó có các thứ ngoài lề khác tương tự struct, class bên C++ không nhỉ ?
Ví dụ nó có tính kích thước, hoặc cấu trúc có giống, có phân biệt char, uchar, short, int, …. như C++ hay không ?

Khi code python mình không cần phải quan tâm về kích thước của biến như trong C++ đâu. Python tự cấp phát để giúp mình không bị overflow như trong C++.

Ví dụ trong C++ mình có 2 biến Int đang giữ giá trị lớn, hoặc làm các công việc thao tác trên số lớn thì dễ bị tràn số. Nhưng trong python thì không phải lo về việc đó.

2 Likes

Mình muốn send một object dạng binary qua một stream thôi thì phải biết chính xác size và cấu trúc của nó mà.

à, lúc đấy thì phải tính lại kích thước của object mình gửi qua, mình chưa làm thế bao giờ, bạn thử với cái này xem https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python

3 Likes

Cụ thể là mình có 1 con server (C++) đang nhận các gói tin tcpip dạng binary gửi về sau đó decode ra thông tin. Các client code C++ thì dễ dàng rồi mình mình gửi luôn cái struct qua rất nhẹ nhàng.
Mà hiện tại python thì phải biết chính xác các byte rồi đẩy từng byte vào 1 mảng rồi gửi đi @@.

Hmm, sao @Duong_Act lại decode bằng tay khổ thế, giờ có nhiều lib để giúp mình communicate giữa client/server qua tcpid mà.

Ví dụ nhé https://stackoverflow.com/questions/13466341/example-for-a-simple-python-client-and-c-server

2 Likes

À như mình nói là dữ liệu của mình là binary mà. Vấn đề là ở chỗ encode/decode dữ liệu ấy chứ không phải communicate.
Ví dụ gửi số int là gửi thẳng 4 byte của nó qua ấy.
Ở đây là gửi một struct chứa nhiều thông tin. Chứ không phải convert ra string để gửi vì như vậy nó rất nặng và bên server decode từ string ra dữ liệu gốc cũng lâu.

1 Like

Không biết bác thử protobuf chưa?

2 Likes

Theo phong cách OOP:

class linhvuc:
    def __init__(self, ten, so):
        self.ten = ten
        self.so = so

a = [None] * 3
sum = 0

def nhap():
    for i in range(3):
        ten = input("Nhap vao ten linh vuc")
        so = input("Nhap vao so lieu")
        a[i] = linhvuc(ten, so)
        sum += a[i].so

P/S: Bỏ ngay dùng fflush(stdin) đi nhé :angry:

2 Likes

Mình chưa nhưng vừa đọc qua có thấy liên quan gì đâu nhỉ ?

bí quá thì xài pybind11 định nghĩa gói tin và các hàm tương ứng cho python =]]

3 Likes

Nó là format trao đổi data như XML, JSON thôi, khác là binary-only. Bên gửi push data vào, gửi đi, bên nhận lấy data encode ra. Không cần để ý đến size hay data layout nữa, protobuf nó lo hết

3 Likes

Vậy chắc dùng cho hệ thống build hết bằng python và làm việc nhàn nhã chút.
Hệ thống của mình chủ yếu xây dựng bằng C vì thiết bị chỉ hỗ trợ ngôn ngữ đó. Chuyển tụi này cho tương đồng chắc khá là nhọc.

4 Likes

Traceback (most recent call last):
File “C:\Lập trình cơ bản\comment.py”, line 13, in
nhap()
File “C:\Lập trình cơ bản\comment.py”, line 11, in nhap
a[i]=linhvuc(ten,so)
IndexError: list assignment index out of range
báo lỗi trên anh ơi, vứt cái sum đi thì được, khó hiểu quá

Phải thêm global sum ở hàm nhập bạn nhé :smiley:

3 Likes

tức là biến toàn cục nào thì khi dùng trong hàm cũng phải khai thành global hở bạn

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?