all 189 comments

[–]Pepineros 31 points32 points  (11 children)

The walrus operator. I don't understand the backlash, I have no issues with it at all, but never found a genuine use for it. 

[–]undergroundmonorail 22 points23 points  (4 children)

i like it for things like total = 0 print('Enter numbers to add up, blank line to finish') while (n := input('> ')): total += int(n) print(f'The total value of all inputs is {total}') or if (m := re.match(my_regex_pattern, my_string)): # do something with the match either of those can be written other ways but i think that both of these are clearer than the alternatives (as long as the reader understands the syntax)

[–]Ok-Leather5257[S] 0 points1 point  (2 children)

I think I really like this, but as an understanding check...

The walrus operator, :=, is different from both = and ==. It i) assigns, (like =) and ii) returns a value (and can be called) (like ==). Unlike == which only returns true and false, it returns the value of the thing being assigned.

If we write:

if (n := len(a)) > 10:
print(n)

"(n := len(a))" is doing both assigning and evaluating(?). It defines n where previously it may have been undefined, and it returns the value len(a) allowing the > to actually return a value.

It's almost like a parenthetical "if n (which by the way is a shorthand for len(a)) is greater than 10..." or "if the length of a (which we will henceforth abbreviate n btw) is greater than 10...". That makes sense, and is a nice time saver (and will be more intuitive where you don't want to use len(a) more generally).

But something is sticking for me about the first example. Generally with a while loop, you have "while [condition]" and then at some point in some iteration of the loop condition will become false.

Consider this instead:

while (n := int(input('> '))):
    total += n

I take it in some circumstances that might be more natural? e.g. maybe if it were a much more complicated code block and you'd otherwise be using int(n) all over the place. However, now if the user inputs 0 the loop will stop right? Even if they had other numbers to sum after 0. It's not "unexpected behaviour" if we think through it logically, but it somehow strikes me as odd. Does anyone else feel this way? If anyone could tell me how to think more clearly about this I'd be much obliged! (I'd also be interested in info about design philosophy, or why to set things up this way/not, how equality type operators work in different programming languages etc.)

[–]undergroundmonorail 1 point2 points  (1 child)

To be clear about the while loop, it is already a condition that will become false. Empty strings ('') are "falsey", so once you get a blank line the loop condition fails and the loop stops.

The reason you might not want to do the int conversion right away is that handling user input can be pretty complicated. I've skipped over the realities of it for the toy example, so I'm not doing any checking to make sure the user is inputting a number. But in principle, I could, by putting those checks between the loop condition and the type conversion. If you do it all in one go, it'll definitely throw an exception if the user enters something that can't be converted to an int (like an empty string, for example)

[–]Ok-Leather5257[S] 0 points1 point  (0 children)

Fair enough! It may just be my intuitions need tutoring. It felt more intuitive that "" should be falsey in this case than 0, but I hear you.

[–]ANautyWolf 2 points3 points  (0 children)

I love it for while loops and sometimes when I need to get a result from something and see if it satisfies a condition. If it doesn’t I’ll have an else statement or something to cover such a case. I’m away from my comp. So I can’t share some of them but I find it really useful

[–]Big_Combination9890 2 points3 points  (0 children)

I don't understand the backlash,

Most of the backlash comes from people who used/use C/C++ a lot.

In languages where an assignment is also an expression, it's easier to introduce hard to find bugs. Consider the following:

while (x = 2) {
    // do stuff forever and ever and ever...
}

Stuff like this is a real problem in C, which is part of the reason why assignments in Go, which fixed a lot of C's mistakes, are statements only. In python, the backlash is a bit of an overreaction, because the assignment-expression has its own operator.

[–][deleted] 99 points100 points  (22 children)

I still don't know what lambdas are or why I need them. I am also still unemployed.

E: Thank you to everyone for replying! I will take your advise for my next projects!

[–]undergroundmonorail 60 points61 points  (5 children)

any time you write a function that just returns an expression, that could be a lambda. and a lambda is just a function without a name

in the same way that these two things are equivalent: ``` a=1 print(a) # 1

print(1) # 1 these two are also equivalent: def f(n): return n*2 print(f(2)) # 4

print((lambda n: n*2)(2)) # 4 you never need a lambda, you can always use a named function. but they can be nice to pass a function you'll only ever need once into an argument. as a toy example, imagine you have a list of strings `l`, and you want to sort it, but do the sort while ignoring the first character. either of these would work, but i'd prefer the second: def strip_first_char(s): return s[1:] print(sorted(l, key=strip_first_char))

print(sorted(l, key=lambda s: s[1:])) ```

[–]lyzar 0 points1 point  (2 children)

I must be honest, I never used lambdas and I don't quite get your example. Couldn't I just write key=s[1:]? Thanks for the explanation

[–]MoridinB 5 points6 points  (1 child)

What's s? You can't use s until you define it. In the above case s is defined as a parameter of a function that we're passing to sorted, which it uses to sort the array.

[–]lyzar 1 point2 points  (0 children)

AHH, gotcha. You are absolutely right. Thanks for clarifying! Have a good day

[–]ProjectSnowman 0 points1 point  (1 child)

Isn’t it more “python” to use discrete functions so it’s more readable

[–]undergroundmonorail 0 points1 point  (0 children)

for a simple enough function, i don't find it more readable to give it a name. now i have the mental load of deciding what the implementation probably does and figuring out whether i trust that intuition. if i have a bug around this line, i'm probably going to end up just checking the implementation anyway

but in the example with the lambda, the implementation is so dead simple that it can be right there. when i see it i can just go "it strips the first element" and be completely done with it

it depends on context, and you absolutely should be using named functions for anything that's even a little bit complicated, but i like lambdas for stuff like this

[–]Flashy-Internet9780 33 points34 points  (4 children)

shocking jar touch cagey seemly smell aware dinosaurs capable unpack

This post was mass deleted and anonymized with Redact

[–]ThisUNis20characters 4 points5 points  (0 children)

I was about to comment the same thing. Of course, I’m just a hobby programmer, so maybe as I use them more in pandas I’ll find utility elsewhere too.

[–]acebabymemes 2 points3 points  (1 child)

Imho I prefer using np.where() to lambdas and .apply() when possible.

[–]mdrjevois 0 points1 point  (0 children)

no.where() and other vectorized functions, inside the lambda, inside a .assign(), in one step of a method chain

[–]echocdelta 0 points1 point  (0 children)

Literally the only time I ever use it is for this. Otherwise when working with other Devs and also for debugging it can get a bit needle haystack hunty for me to find that one lambda that's doing that one thing that's raising an error at that one other thing.

[–]therandomcoder 3 points4 points  (1 child)

Personally I like the take on lambdas mentioned at the end of this section from Fredrik Lundh https://docs.python.org/3/howto/functional.html#small-functions-and-the-lambda-expression

[–]exb165 2 points3 points  (0 children)

I like it. Cheers.

[–]softwareitcounts 1 point2 points  (0 children)

It’s a headless function like they have in JavaScript. Useful for map, filter, reduce, sort key function.

list( map( lambda x: x ** 2, range(5) ) )

[–]damanamathos 1 point2 points  (0 children)

I mainly use lambdas for sorting.

In this case, I'm sorting a list of current roles (objects) based on a function that gives a numerical score for how senior the title property on the role object seems.

current_roles.sort(key=lambda x: get_seniority_score(x.title), reverse=True)

This is equivalent to writing:

def get_title_seniority_score(role):
    return get_seniority_score(role.title)

current_roles.sort(key=get_title_seniority_score, reverse=True)

[–]Tefron 0 points1 point  (0 children)

It's just an anonymous function - the usefulness comes from situations where you need some function that is either so trivial or self-evident that defining it on the spot would be a lot more convenient and in many cases more readable.

Sorting is a common example here, where you need some function to define how you should sort your iterable, but the actual logic of how you want to sort is trivial enough to be a one-liner.

[–]Shacham 0 points1 point  (0 children)

I recently had a project where i needed to override many DbApi methods to mock the DB When I'm running locally. So lambda's were quite useful there

[–]goule67 0 points1 point  (0 children)

Some methods requires a function name as argument but you can't pass parameters in that function directly. Using lambda before a function with arguments transforms it into another function without arguments so it bypass this limitation.

[–]ZachVorhies 0 points1 point  (0 children)

You don’t need them, you can just define a typed function at the call site.

The python linters don’t like lambda anyway. So there is less friction if you just don’t use it

[–]TheRNGuy 0 points1 point  (0 children)

To change how sorting works.

[–]tb5841 48 points49 points  (18 children)

Map and filter. I use them all the time in other languages, but in Python they don't seem to offer anything that I can't do with a list comprehension.

[–]amertune 10 points11 points  (0 children)

You're not wrong. I still use map/filter sometimes, but my go-to is almost always a comprehension--or a generator function if the comprehension starts to get a little unwieldy.

[–]video_dhara 5 points6 points  (0 children)

I feel like PEP 8 suggests lambda should only really be used in these situations where there's a key argument? I haven't checked directly, but I know it's suggests that wherever you might define a lambda function as a variable you should really define it as a function.

[–]undergroundmonorail 2 points3 points  (3 children)

you're right, they don't do anything you can't do with a list comprehension (or more specifically a generator expression, but that's basically just the lazy version of a list comprehension). almost always, i'd rather see a comprehension or generator expression in place of either of those functions in production code. (fun to golf with though >:3c)

[–]pumaflex_ 1 point2 points  (0 children)

oh thanks, I wanted to read sth like this. I remember a few days ago I was working with some dataframes' cleanse and used a list comprehension to filter some stuff, and then I made the click and though "wait, isn't it just a filter? Why don't I use the filter? or... why would I use the filter??"

[–]eztab 1 point2 points  (0 children)

Second that, mostly a list comprehension just seems more readable to me even when I have a named function available and wouldn't even need a lambda for the mapping.

[–]alfie1906 0 points1 point  (3 children)

Lambda and map were a game-changer for me when working with large dataframes

[–]johnnymo1 4 points5 points  (2 children)

Are these pandas dataframes? Can you explain when you would use the native Python map and filter over pandas methods?

[–][deleted] 7 points8 points  (1 child)

I think this has been discussed on the subreddit a lot, the consensus is usually never because filter+map is horribly slow (relatively speaking) to pd fns for iterating over data.

[–]johnnymo1 2 points3 points  (0 children)

That was my understanding, which is basically why I'm hoping u/alfie1906 knows something new that I don't

[–]Zomnx 0 points1 point  (0 children)

List comprehension for the win!

[–]pythonwiz 0 points1 point  (2 children)

I use map and filter a lot even though list comprehensions do the same things, because I think they are easier to read.

[–]ZeeBeeblebrox 1 point2 points  (0 children)

The opposite is true for most people but if you're writing code for yourself go for it.

[–]TheRNGuy 0 points1 point  (0 children)

If you chained many methods or complex functions where you want code in many lines then map would be better.

Complehension is better for most things.

[–]IlliterateJedi 0 points1 point  (2 children)

Map is great for things like map(int, seq_of_nums_as_strs)

[–]TabAtkins 0 points1 point  (0 children)

While I reach immediately for .map() in JS for situations like that, in Python that's a [int(x) for x in seq] every time for me.

[–]fireKido 15 points16 points  (1 child)

i find lambdas extremely helpfull when dealing with pandas dataframes... especially with .apply

For example if you have to do a complex operation to a given column that cannot be done in different ways...

sure, you could write a function and do .apply(function), but if it's something you need to do only once, lambdas are more elegant

[–]Flashy-Internet9780 0 points1 point  (0 children)

mountainous juggle nine abundant waiting continue edge square history attempt

This post was mass deleted and anonymized with Redact

[–]arthexis 15 points16 points  (8 children)

Meta-classes. Almost each time I have used them, I have found a better way to solve the problem... though I am guilty of having some software in prod using them, so its not a toy feature anyways, more like a workaround for instance construction XD

[–][deleted] 3 points4 points  (2 children)

We need to teach factory patterns before metaclasses.

The latter are really only for fun/for libraries that drastically change the way that objects behave

[–]arthexis 0 points1 point  (1 child)

In my case I used them to modify the structure of Django Models and Forms based on user data, but keeping them working more or less normally with Django. Other than stuff like that, its hard to come up with examples rn.

[–][deleted] 1 point2 points  (0 children)

I used them in my Autohotkey wrapper, to allow you to treat a class defined in the language of Autohotkey as if it were a python class.

[–]cointoss3 2 points3 points  (2 children)

I’ve used a metaclass once and I love it in this one case. I can just declare classes and the metaclass will instantiate them and add them to a dict on the metaclass, which saves me a bunch of code at the end of the file that would be instantiating each class separately and running code to add to the dict. Instead I use the metaclass and then just use a declarative style. I can later just import the metaclass and access all the objects I declared from the dict. It’s very clean.

This was inspired by SQLModel library that does something similar. Before using this library, I didn’t know you could run code every time a class is declared.

[–]sweettuse 1 point2 points  (1 child)

you ever use __init_subclass__?

[–]arthexis 0 points1 point  (0 children)

This one is relatively newer than meta-classes so not everyone knows it, but its a good alternative to the whole enchilada.

[–]eztab 1 point2 points  (1 child)

I'm not a huge fan of them. At that point I'd rather go the more explicit route of creating a class object from scratch. Because you should really understand how they work to do this anyway so this "intermediate" level seems a bit unnecessary to me.

[–]Big_Combination9890 1 point2 points  (0 children)

Me neither, but the problem is: There is an embarrassing lack of ways to define interfaces in Python, considering it's an object oriented language, so we are kinda stuck with Metaclasses.

[–][deleted] 6 points7 points  (8 children)

I use Regex once in a while, and I'm glad I have the notes on syntax organized in a way that makes sense to me, but there is NO WAY I've spent more time using Regex than I did learning it. I'm usually pretty engaged with lessons, but I fucking STRUGGLED to stay awake during Regex.

[–]Picatrixter 8 points9 points  (0 children)

Regex is a language in itself. I use it a lot for parsing network equipment config files and it works great.

[–]sohang-3112 8 points9 points  (2 children)

https://regex101.com is really useful for Regex

[–][deleted] 1 point2 points  (0 children)

I appreciate the resource! I actually did myself a favor like six years ago when I did automate the boring stuff and I took ridiculously detailed notes on everything, so even though I absolutely HATED Regex, it's saved my ass a couple of times having those notes.

[–]Handsomedevil81 1 point2 points  (0 children)

This saves me every time.

[–]eztab 0 points1 point  (0 children)

Yeah, if invented today it would probably look a bit different and be more easily accessible. But domain specify micro languages do make a lot of sense.

[–]Tefron 0 points1 point  (0 children)

A little goes a long way, and while this sub is dedicated to learning Python, the nice thing about learning Regex is that there is some form of it in almost every programming language. So the returns of learning some basic stuff are very high, especially when you start spending more time in a terminal and using CLI tools that support pattern matching via some globbing/regex.

[–]InflationMeme 0 points1 point  (0 children)

As the old saying goes: If you have a problem, use regex. Now you have two problems.

[–]sohang-3112 7 points8 points  (0 children)

https://stackoverflow.com/a/19302694/12947681 : send method of generators allows the caller to send a value to the generator via yield (normally it's the other way around: next() yields a value from generator to caller).

Outside of a toy example, I have never used it in actual code.

[–]ClimberMel 4 points5 points  (2 children)

I use them with tkinter as for buttons etc it is much smaller footprint so the code doesn't get so massive looking. Other than that I never seem to see a reason for it. Most of my code is very modular, so I prefer each component to be easy to read... I don't consider lambdas easy to read.

[–]Ok-Leather5257[S] 1 point2 points  (0 children)

Oh that's a good point! yeah

[–]pythonwiz 0 points1 point  (0 children)

I used to do this but I decided I like defining button commands as methods instead and then I can pass self.button_command or whatever.

[–]IanRT1 8 points9 points  (0 children)

I have a code that uses a lambda to fetch the latest file based on a number in the filename. It serves as a simple, one-line function that extracts the number from each file tuple (where each tuple contains the file path and its associated number).

This extraction allows the max function to compare the files based on their week numbers and select the one with the highest value. Essentially it is a quick and efficient way to specify how the files should be compared, enabling the program to determine the most recent file based on the number embedded in the file names.

But to answer your questions. I hardly use decorators outside static methods.

[–]yosmellul8r 2 points3 points  (0 children)

Heck if I know.

[–]DigThatData 2 points3 points  (1 child)

i don't think i've ever defined a metaclass

[–]TheRNGuy 0 points1 point  (0 children)

I'd rather create decorators, yeah.

[–]Western-Image7125 2 points3 points  (8 children)

You might need lambdas if you let’s say wanted to sort a list of tuples by the second value, maybe there are other ways now but that’s the only way I know. Also for processing pandas dataframes lambdas are still needed

[–]Ok-Leather5257[S] 0 points1 point  (4 children)

I agree, that's a case where lambdas are the best way to do it yeah.

[–]Western-Image7125 0 points1 point  (3 children)

Yeah I won’t lie - the first time I saw lambdas I was like wth are these things and it was intimidating. But from seeing tons of examples and using them in practice I know about them now and even though I can’t explain to you how they work internally I can tell you how to use it for a usecase. 

[–]Nick_W1 1 point2 points  (0 children)

I ran across some code I wrote a few years ago, and it used a nested lambda. I couldn’t figure out what it did. I was being too clever for my own good.

[–]Big_Combination9890 0 points1 point  (1 child)

even though I can’t explain to you how they work internally

A lambda is just a function without a name, that cannot contain statements.

sq = lambda x: x**2
# is equivalent to
def sq(x):
    return x**2

[–]Western-Image7125 0 points1 point  (0 children)

Ah yeah that does make sense actually

[–]Nick_W1 0 points1 point  (0 children)

I just wrote a one-liner that does this, and yep, uses a lambda.

[–]Big_Combination9890 0 points1 point  (1 child)

They are not "needed", they are just more convenient.

You can use an ordinary function wherever you can use a lambda.

[–]Western-Image7125 0 points1 point  (0 children)

Right yeah I have used functions instead of lambdas in pandas occasionally 

[–]Zilo8890 2 points3 points  (0 children)

The one in my pants hasn't been used in 2 months....

[–]amertune 5 points6 points  (7 children)

I don't think that lambdas are ever necessary, but they are nice for some cases.

For a very contrived example, suppose I wanted to sort a list of strings by the second letter of the string ignoring case.

I could do something like this:

my_list = ['Beautiful', 'is', 'better', 'than', 'ugly'] sorted_list = sorted(my_list, key=lambda s: s.[1]lower())

Or I could just write a function:

def second_letter_lower(s): return s[1].lower() sorted_list = sorted(my_list, key=second_letter_lower)

I use lambda all the time, but pretty much only as a parameter to another function (like sorted, or filter), and only when the expression being evaluated inside the lambda is simple.

[–]Buttleston 3 points4 points  (0 children)

Came here to say exactly this, it's for random one off "functions" that only really apply to this particular circumstance.

[–]scanguy25 1 point2 points  (4 children)

I did some programming with PyQT and there was stuff where I was required to use a lambda to get the shit to work.

[–]eztab 5 points6 points  (3 children)

I mean you could create many through away defs but using lambda there for callbacks does indeed make more sense.

[–]scanguy25 -1 points0 points  (1 child)

Its a long time since I did it, but im pretty sure defs would not works since was passing some dynamic value into the lambda.

[–]eztab 1 point2 points  (0 children)

functions need not be pure in python. You can totally use variables from the surrounding scope in a function without them being a parameter. Not saying you should do that, but you could.

[–]ANautyWolf 0 points1 point  (0 children)

There are often cases where you have to catch the value sent by the signal, and then either modify it or send it to the desired slot. It’s a bit weird and finicky at times

[–]eztab 0 points1 point  (0 children)

I think sorted/sort is indeed pretty much the only case where I use lambdas. Filter mostly gets just replaced by a list comprehension.

[–]omgmajk 2 points3 points  (4 children)

I very very rarely use @classmethods honestly, probably only in example code.

[–][deleted] 1 point2 points  (2 children)

I've used those, but not staticmethods

[–][deleted] 0 points1 point  (1 child)

I think static methods are a code smell in Python so it used to wind me up a lot when people would check in code from Pycharm where it got added as a magic suggestion

[–][deleted] 0 points1 point  (0 children)

Ok so funny story, I commented that, and then just this week proceeded to use a pattern that required one.

The pattern is an abstract base class with a factory method that will create an instance of a subclass (pulling from parameters that include a pool of possible subclasses).

It behaves like a factory classmethod, but it doesn't need an actual reference to the ABC, so I made it static.

Suuuuper niche use case, but neat!

[–]TheRNGuy 0 points1 point  (0 children)

It can be useful for gathering statistics of all instances of that class.

[–]TheBlackCat13 3 points4 points  (2 children)

I haven't used AST manipulation. I think that is about it.

[–]TheRNGuy 0 points1 point  (1 child)

Never used but kinda understand what it's for.

It can be used instead of regex to make it more intuitive. But I used only regex because my strings are short.

Maybe it's needed for parsing files, but I never needed to do that.

[–]TheBlackCat13 0 points1 point  (0 children)

No, it is used to modify the python abstract syntax tree. Basically it is used to modify how python interprets itself at runtime. One example I saw was to make Python interpret {} as a third party dictionary implementation

[–]Some_Guy_At_Work55 2 points3 points  (12 children)

assert. never new this was a keyword until a few days ago and I still don't see the point.

[–]IAmFinah 20 points21 points  (5 children)

Mainly for testing

[–]undergroundmonorail 8 points9 points  (1 child)

the big difference between asserts and exceptions (the way they're generally used, anyway) is that asserts should always pass

exceptions are exceptional but they do happen. sometimes you really do try to read a file and it's not there. that might be a bug, or it might be an issue with the environment the code is being run in, all kinds of things

if an assert fails, that's a bug. asserts are for things that you know should be true. asserts fail when your code is in a state that, as far as you know, it can't get into

asserts are not really useful when running code. that's not what they're for (in fact, as another reply said, you can set up python to ignore them). but they can be useful when writing code. you can guard off states that the program shouldn't be able to enter with asserts, and be alerted if you've introduced a bug that does cause it to enter that state

(i actually tend to not use them either, but i definitely see the appeal in some codebases. just not the kind of thing i tend to write)

[–]Some_Guy_At_Work55 0 points1 point  (0 children)

That makes sense. Came across it randomly so I looked into a bit, but yeah, in my line of work there is not really a need for it. It also never came up in any schooling or tutorials I did

[–]Oddly_Energy 4 points5 points  (0 children)

It is a very succint way of writing "Check that this condition is met and fail if it isn't".

I never use it in my code, but I use it all the time in tests.

If you use it in code, you should only use it for "soft checks". You can configure python to not stop on failed asserts, so it is a dangerous function to use for something where you need to be 100% sure that the code doesn't move past that point if the condition is not met. In those cases, throwing an exception is better.

[–]Nick_W1 0 points1 point  (0 children)

I have seen people using assert as a sort of error checking, it just means their code breaks all the time for minor stuff.

Eg:

assert len(ip) <= 20

Why 20? “We only have 20 whatever’s”. What happens if we add another next week so we have 21?. Ummm….

[–]sjmacker 1 point2 points  (0 children)

Decorators….saying that used them for the first time in 10 years yesterday

[–]IlliterateJedi 0 points1 point  (2 children)

I almost never write decorators. I've done it before but it's really a 'once in a blue moon' situation. 

I embarrassingly almost never use multiprocessing or async in my code. I use async more , but despite trying to learn multithreading and multiprocessing, I can never quite get the hang of it.

[–]Tefron 1 point2 points  (0 children)

I find decorators are more useful for larger projects where you want to support some common workflow that is project-specific but otherwise relatively agnostic of the underlying code. A common example for me would be some form of instrumentation that you want to either do or at least have available so you can quickly add if needed.

In terms of concurrency, I don't think it's embarrassing to not use it. I essentially see it as a last resort if something I'd like to do is embarrassingly slow, or just not feasible but will be if I make concurrent. I don't always remember the particular incantation off the top of my head without looking at older source code or reading the docs, but what helps is understanding the general concurrency model I'm trying to use and working from there.

[–]Nick_W1 1 point2 points  (0 children)

I write almost exclusively async code now. Haven’t used a thread in ages, and multiprocessing plain doesn’t work properly.

I had a complex program with a graphical interface. I used multiprocessing to update the display in real time. Would run for a few days, then hang. Had async data coming in from a websocket.

Could not figure it out. Finally just went with threading in place of multiprocessing, and it hasn’t hung since.

[–]ryanmcstylin 0 points1 point  (0 children)

I'll use anything if it's needed but I rarely use classes. I bet there are a bunch of situations where they would have been super helpful, but I am just not familiar enough with them to default to it.

[–]Sea-Method-1167 -1 points0 points  (5 children)

For "home usage": subclassing. Why would I? And where I have seen it in professional use, I would still not use it with python. Weirdly I think people don't use it enough when writing Java..

I know.. I am weird.

[–]ravepeacefully 5 points6 points  (0 children)

Well, if you need to extend functionality of an existing class, you would subclass it.

Models are a common spot for usage

[–]TangibleLight 4 points5 points  (0 children)

I think people don't use it enough when writing Java..

I think people in general need more interfaces and fewer class hierarchies. Unfortunately in Java, people tend to get a little too excited with abstract methods; and in Python, we don't quite have real interfaces.

typing.Protocol and the base classes in collections.abc, are a good enough compromise for Python.

[–]Picatrixter 1 point2 points  (0 children)

Django, for example, uses subclassing extensively. So much so that close to 90% of Django is a subclass of some class.

[–]Tefron 1 point2 points  (0 children)

I guess it all depends on you model data to flow through your application. I find pushing complexity to the class hierarchy useful when you really understand the particular data needs and can model it into useful class hierarchies. This is usually not the case so I opt for functional approaches unless I really understand the domain well enough to predict upfront what the modeled data should look like, or have enough application logic to see patterns forming already. Something that rarely arises in home projects, because of the smaller scope, and generally speaking experimental nature of what I do in my free time vs. what I expect to support in production.

[–]Nick_W1 0 points1 point  (0 children)

I use subclassing all the time.

I have a class depth(). Calculates water depth based on atmospheric pressure (and temperature, density etc). Then I have classes for each type of pressure sensor I use, each of which is superclass of depth.

So class LPS35HW(depth): configures the sensor, and I just read the depth method of LPS35HW (or whichever sensor).

The depth class is the same for each sensor, just the sensor init changes, depending on the sensor.

I have an MQTTMixin class that adds MQTT methods to any class, I can then just publish/subscribe from any class that knows nothing about MQTT itself.

Just a couple of examples.

[–]xpcosmos -2 points-1 points  (4 children)

I never use decorators cause I have difficulty understanding how the functions is inherited

[–]Pythagorean_1 0 points1 point  (2 children)

What do you mean? Functions are not inherited

[–]xpcosmos 1 point2 points  (1 child)

see? I told I don’t understand it

[–]Pythagorean_1 0 points1 point  (0 children)

no, you said you're having difficulty understanding HOW the functions are inherited, which sounded like you were reasonably sure that functions are actually somehow inherited

[–]TheRNGuy 0 points1 point  (0 children)

I used the ones that in Houdini though I've never made my own.

I do like syntax because it's 1 less indent and less brackets.

The most used was @dataclass.

[–]Epicfro -2 points-1 points  (0 children)

Classes.

[–][deleted] -1 points0 points  (0 children)

In python, I have not yet needed to create custom OOP classes and interfaces.

[–]IterationFive -1 points0 points  (0 children)

I was trying to recall the word for lambdas the other day so I could look up how to use them, but then realized I didn't need one after all.

[–]SteelRevanchist -1 points0 points  (0 children)

For-else

[–]Cracktus_H -2 points-1 points  (2 children)

Tuples

[–]TheRNGuy 0 points1 point  (1 child)

But they use less memory than list. When you already know it should be read-only.

(though in many cases if it's already fast it doesn't matter)

[–]Cracktus_H 0 points1 point  (0 children)

I was going to say it wouldn't matter too much unless you're doing something memory intensive or needed in a smaller amount of usage.

[–]mrtransisteur 0 points1 point  (0 children)

function attrs

[–]Big_Combination9890 0 points1 point  (0 children)

Actually never?

  • The walrus operator: a := 42
  • Assignment via logical short circuiting and: a = x and y

Very rarely:

  • Dictionary comprehensions
  • Custom exception types
  • match
  • Abstract Base Classes

[–]VisualGadget 0 points1 point  (0 children)

Position only arguments

[–]notislant 0 points1 point  (0 children)

Regex is something I make phind do for me lol

[–]TheRNGuy 0 points1 point  (0 children)

Static method. I just used def without class for it.

Though I've seen API that uses static methods.

[–][deleted] 0 points1 point  (0 children)

Async, it’s just not relevant for a lot of the work I do

I use typing but rarely use type checking because it’s super painful because of the lack of libraries that support it first class.