DEV Community

Cover image for Python classes vs Rust structures
Antonov Mike
Antonov Mike

Posted on • Updated on

Python classes vs Rust structures

I guess I should supplement my previous post. I have received valid criticism in private messages. Thank you for that. Now I'm going to try to talk about classes and structures.

These are two ways of defining custom data types in their respective languages, but they have some notable differences in their syntax, features, and usage.

Some of the similarities are:

1) Both Python classes and Rust structures can have fields that store data and methods that define behavior.
2) Both Python classes and Rust structures can implement inheritance, polymorphism, and encapsulation, which are the core principles of object-oriented programming.
3) Both Python classes and Rust structures can use constructors to initialize their instances with default or custom values.

Some of the differences are:

1) Python classes are dynamic and flexible, while Rust structures are static and strict. Python classes can add or remove fields and methods at runtime, and use decorators and metaclasses to modify their behavior. Rust structures have fixed fields and methods, and use traits and macros to extend their functionality.
2) Python classes use the self keyword to refer to the current instance within a method, while Rust structures use the self, &self, or &mut self parameters to indicate the ownership and mutability of the instance.
3) Python classes support multiple inheritance, which means a class can inherit from more than one class at the same time. Rust structures do not support multiple inheritance, but a structure can implement multiple traits and a trait can require multiple traits as bounds.

Python has a built-in garbage collector that manages the memory, while Rust uses the ownership and borrowing system to ensure memory safety and prevent memory leaks.

An example of how we can implement Player in Python and Rust

class Player:
    def __init__(self, name, color):
        self.name = name
        self.color = color
        pass

    def valid_player(self, piece_color):
        if self.color == piece_color:
            return True
        else:
            return False
Enter fullscreen mode Exit fullscreen mode
pub struct Player {
   name: String,
   color: String,
}

impl Player {
   pub fn new(name: String, color: String) -> Player {
       Player { name, color }
   }

   pub fn valid_player(&self, piece_color: &str) -> bool {
       self.color == piece_color
   }
}
Enter fullscreen mode Exit fullscreen mode

Image created by Bing and edited by me

Other articles about the similarities and differences between Rust and Python

  1. Python Classes vs. Rust Traits
  2. Python classes vs Rust structures
  3. Polymorphism in Rust and Python
  4. Abstraction in Rust and Python
  5. Encapsulation in Rust and Python
  6. Composition in Rust and Python

Top comments (16)

Collapse
 
slobodan4nista profile image
Slobi

We don't talk enough about Rust awesome OOP approach. But borrow-checker a is pain for lightweight programming and mem stuff in general.

Collapse
 
__masashi__ profile image
Masashi

When you start programming in rust for something that needs to be low level and performant, you generally have to choose between C, C++ and Rust(other options exist too). Rust is pretty different from both of the other options, programmatically but in the end, they all get the job done. Rust, however, removed all hassles of "check for memory leaks", "check for segfaults", and all that.
[Exceptions apply when you are manually mutating memory or doing something which is "unsafe"]

TL;DR: Rust is "safe"r than the others. And faster than the high level options.

Collapse
 
antonov_mike profile image
Antonov Mike

Hi, thank you for your comment. I appreciate your insight on Rust and its benefits over other low-level languages. It sounds like you have a lot of experience with Rust. I'm a beginner myself, so I'm still learning the ropes. Today I hardly do Rust anymore and have switched completely to Python (you can't find a job in Rust without experience). But I'm interested in the differences between the two. Have you ever compared them or used them in your projects? I would love to hear your thoughts on the similarities and differences between them.

Thread Thread
 
slobodan4nista profile image
Slobi • Edited

I used Python throughout my studies, after that I did OpenCV project and on my last job a bundle of micro services, I relay enjoy working with it. Since it beginnings I was interested in Rust, it had very good promises, so I learned it on my spare time, most of my experience is in connection with WASM. I had one client that was working on some drawing app in Rust, so there I had my fare share of working with Rust on a large scale. I also come with C++, Java, C# background and now I use JavaScript for everything.
Sorry for my large introduction.
Here is my take:
Python is unique, has great ideas about syntax, OOP, has setattr and getattr. My favorite way to go trough range of number is from python, this simple for i in range(1, 10, 2):. It uses generators as no other language. On the other hand, it is easier to miss indentation and put some expression out of the wanted code block. It just recently got type annotations, when you want to do byte operations and you don't have a lib for that and you want speed you must write it is C. Good thing that is one of easiest C lib integration processes. But then it beets the purpose of easy python. In large projects it stands the same as any other scripting language, you need discipline to make it readable and maintainable.
Rust is also unique but falls in C like family syntax wise. I like that data and methods are separated, you can define any method to any data structure, so that makes it very extendable. The Enum system in Rust is something that I have never encountered and I love it, it substitutes so much code from classical OOP language. Lambda functions look strange in OOP language but in rust it feels natural. I like the way object type represents if object is stored in stack or hip (Box generic). When Rust compiles there is almost no way to get runtime error, compiler is so good at predicting the fail state that you can make it a game to make it break in runtime. Compiler puts on developer so may rules to follow, so the learning curve is steep, but after you get all the rules there is a far less things to think about in comparison to large C++ project. You have to twist your view of program to make it work, so when you don't use Rust you miss many features but you don't miss the twist.

While not using:
In Python I forget some syntax, like what means arr[-1:1:-1].
In Rust I forget how to think and it hurts every time I need to relearn.

Sorry for longer answer, feel free to reach out and ask questions.
I am by no means expert, I like to code, I like to play and I earn on the way.
I might be wrong about many things because knowledge evaporates.

Thread Thread
 
antonov_mike profile image
Antonov Mike

Nothing to be sorry about here, it was interesting. You seem to have quite a lot of experience. I spent two years learning Rust (yes, it was my mistake) from scratch with no IT background and got only depression and a desire to change programming language, because you can't get a job without 3 years of experience. But Rust is still interesting of course. It can be (was) interesting to dig into it.

Thread Thread
 
slobodan4nista profile image
Slobi

I would not say that it was a mistake, it may be a less efficient way, and I can imagine how your Python programming is influenced by Rust experience. You may field in initial idea of being a Rust professional, it should be considered a Chad Move, a flex of what you dared to try taking in account previous experience.
I don't know what is up with programming, so may of us suffers same conditions and it is not about the language. Mostly we are overwhelmed by wast landscape of languages, libraries, and disciplines, it can fell like a Sisyphus work to keep the track. And all the work we've done is going to be deprecated in 2 years if it gets to be used at all.
So we are left to play with code and ideas, find our niche that is applicable to industry and enjoy other things in life, like family, friends and motorcycles.

Thread Thread
 
antonov_mike profile image
Antonov Mike

Depends on time spent, current situation and age. The only thing left in my life is my laptop, I need to reacquire the rest before I get too old ๐Ÿ˜…

Thread Thread
 
slobodan4nista profile image
Slobi

I believe that you will :D You have all the right ingredients.
All the best!

Thread Thread
 
antonov_mike profile image
Antonov Mike

Thank you I do my best

Thread Thread
 
proteusiq profile image
Prayson Wilfred Daniel

I mainly learning and using Rust to speed Python ๐Ÿ˜‚. Using PyO3 and Maturin to help me move between ๐Ÿฆ€ and ๐Ÿ.

Collapse
 
slobodan4nista profile image
Slobi

Thank you for taking time to look at my point :D

You've got a point there, and I totally get it. Rust is a real player in low-level multi threaded programming, and I've been using it as a WASM booster, it's fantastic for that. The syntax is clean, and the performance rivals C.
However, and you've probably felt this too, in single-threaded applications like web, all that safety emphasis can feel like a bit too much. So, for developers like me who want a step beyond JS/TS but aren't willing to commit to the whole Rust, there is no competitor. Rust has awesome syntax and great performance, minus some of the safety hassle. There should be a sweet spot where I could write Rust like syntax, have type safety that goes with it, but with some implicit, not perfect, semi automatic memory management that wont break under single thread. Working with something like that would give a chance for the web to break out the JS chains. This could happen if JS implemented some of type safety form the Rust, Rust made mode for single tread (easier but they are sunburn so it wont happen), or we wait/make an new one inspired by thees.

Collapse
 
antonov_mike profile image
Antonov Mike

Yes, something like this is what I would prefer to write in Python ๐Ÿ˜…

Collapse
 
proteusiq profile image
Prayson Wilfred Daniel • Edited

Could we refactor Python code to

from typing import Self

class Player:

    __slots__ = ["name", "color"]

    def __init__(self, name: str, color: str) -> Self:
        self.name = name
        self.color = color

    def valid_player(self, piece_color: str) -> bool:
        return self.color == piece_color
Enter fullscreen mode Exit fullscreen mode

I think this looks more like the rust version and also capture the developers goal that is enforced in ๐Ÿฆ€ but not in ๐Ÿ.

We could extend with metaclass to enforce more restriction.

Collapse
 
antonov_mike profile image
Antonov Mike

Oh thanks I guess I should try this approach

Collapse
 
fabricehategekimana profile image
fabriceHategekimana

Nice post ! As a Rust enthusiast I have to add something interesting:

  • Rust's structs are not the only way to create new type. There are enums, tuples and tuple structs too.
  • You can extends the behaviour of any type (structs, enums, i32, fn(),...) at any moment in your code in a secure way by implementing traits to those types
  • In Rust you don't have proper "methods" those are still functions in their own way but can be called as method because of the uniform function call functionality so you can call any implemented method in two ways (variable.function() or Type:::function(variable))

All the best !

Collapse
 
antonov_mike profile image
Antonov Mike

Great appendix, thank you very much ๐Ÿ˜Ž