How to simulate a C struct in Python

0

I want to do is create a class called Person containing three items (name 'str', age 'int' and dni 'int') in turn have a separate function that is responsible for filling those fields to a person xy so save the data of that person x inside a file such as 'Personas.dat'. That the code is re-usable so that each time you call the function you can load more and more people.

I can show you what I want by code in C:

typedef struct
{
char nombreApellido[50];
int dni;
int edad;
} Persona;


Persona CargarStructP()
{
Persona a;
fflush(stdin);
printf("--->Ingrese nombre y apellido:\n");
gets((a).nombreApellido);
printf("--->Ingrese DNI:\n");
scanf("%i",&(a).dni);
printf("--->Ingrese edad:\n");
scanf("%i",&(a).edad);
printf("\n");
return a;
}

void CargarPersonas()
{
FILE *registroP = fopen("Personas.dat", "ab");
char control = 's';
Persona a;
while(control == 's' )
{
    a= CargarStructP();
    fwrite(&a, sizeof (Paciente), 1, registroP);
    fflush(stdin);
    printf("Desea continuar [s/n]");
    fflush(stdin);
    scanf("%c", &control);
}
fclose(registroP);
}

void MostrarPersonas(Persona a)
{
printf("----------------------------------------------------");
printf("\n");
printf("PERSONA");
printf("\n");
printf("-Nombre y apellido : %s", a.nombreApellido);
printf("\n");
printf("-DNI: %i",a.dni);
printf("\n");
printf("-Edad: %i", a.edad);
printf("\n");
printf("----------------------------------------------------");
}

Good basically it would be to load data to a class that in this case is People and that to save it in a file and that each data is stored specifically in a person X. If any one knows how to express this in Python or if he can give me some TIP about How to get to approximately a similar result would be very grateful. Thank you very much everyone!

    
asked by Gerónimo Membiela 26.12.2018 в 10:56
source

1 answer

3

Python has no structures, but it has several other types of data that can be used for the same. I indicate some possibilities:

Tuples (disadvised)

A tuple is a group of data, in parentheses and separated by commas. Each element of the tuple can be of a different type. Then a person could be a tuple of three values, the name, the DNI and the age. So:

persona = ("Manolo", 108761234, 23)

You can access the particular fields of the tuple by the place they occupy, as if they were an array of C. So persona[0] would be the name, persona[1] the DNI, etc. Python knows how to directly print a tuple without you having to iterate through it:

>>> print(persona)
("Manolo", 108761234, 23)

The tuple once created can not be modified. This can be useful in many cases, but not in others. It depends on the use you are going to give it.

The great disadvantage of the tuple is that it is not very readable, because you have to remember in what order the data are stored in order to refer to them.

Dictionaries

A dictionary looks like the syntax of an array of C, since its elements are accessed by bracketing the "index", only in this case the "index" does not have to be integer, but it can be of many other types. A particular case is to use strings as "index" (in fact, in dictionaries the "indices" are called claves ), and thus those strings would be equivalent to the names of the fields of a structure C.

For example:

persona = {}  # Esto es un diccionario vacío
persona["nombre"] = "Manolo"
persona["dni"] = 108761234
persona["edad"] = 23

Python knows how to print dictionaries directly, although the order in which their fields appear is not predictable (except from Python 3.7+, which respects the order in which they were assigned).

>>> print(persona)
{'nombre': 'Manolo', 'dni': 108761234, 'edad': 23}

Objects

Using object-oriented programming, you can define a class Persona , which has attributes for the data you want to save, and methods to operate on those fields. Syntactically, this is what most resembles a C structure.

In python you could declare the person class as simply as:

class Persona:
   pass

This creates a class without any attributes or methods. However, since in Python everything is dynamic, you can create attributes a posteriori, by instantiating this class in an object and adding the desired information to that object:

persona = Persona()  # Crea un objeto nuevo, a partir de esa clase
persona.nombre = "Manolo"
persona.dni = 108761234
persona.edad = 23
# Se le asignan atributos

However, this is not the usual way of working. The normal thing is that the attributes are assigned to the object through its constructor which is a function that is executed when a new object of that class is created, and that can receive as parameters the data in question, so that it stores them in the corresponding attributes.

In python the constructor is written by adding a method called __init__() to the class. This method receives at least a first parameter called self that represents the object that is being created, and then all the additional parameters that you want to put on it. In our case:

class Persona:
    def __init__(self, nombre, dni, edad):
         self.nombre = nombre
         self.dni = dni
         self.edad = edad

With the constructor, the creation of an object would be like this:

persona = Persona("Manolo", 108761234, 23)

As you see, it resembles the initial tuple in some way, but now with the advantage that the name of the attributes is used to access the data instead of its position (which does not really exist). That is, persona.edad would be worth 23 ( persona[2] does not exist).

Python by default "does not know" how to print an object, what it prints is the class it belongs to and the memory address in which it is stored:

>>> print(persona)
<__main__.Persona at 0x7fc0b2d1cfd0>

This is not very useful, but you can define your own method __str__() , inside the class Persona that returns a string, and then Python will use that method when you have to print it.

There is a lot more to tell about object-oriented programming (OOP) but this is not the place. You should read any of the many tutorials on programming in Python.

Namedtuples

When a class is going to be used only to store information, and not to provide functionality, that is, when we purely want the equivalent of a struct of C, we can use the type namedtuple , which is mix between a tuple and a class. Internally it stores the data in a tuple, but it allows access to them by its name as well as by its position.

It is specially indicated for the case in which we also want the data to be immutable (which can not be modified once they have been saved).

Example of this case:

from collections import namedtuple

Persona = namedtuple("Persona", ["nombre", "dni", "edad"])
# Persona es una clase, de la que puedo instanciar objetos
persona = Persona(nombre="Manolo", dni=108761234, edad=23)

Now you can access the name both by persona[0] as per persona.nombre .

In addition, the class Persona created with namedtuple() incorporates methods so that when printing the object the representation is easily readable:

>>> print(persona)
Persona(nombre='Manolo', dni=108761234, edad=23)
    
answered by 26.12.2018 / 11:57
source