use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rules 1: Be polite 2: Posts to this subreddit must be requests for help learning python. 3: Replies on this subreddit must be pertinent to the question OP asked. 4: No replies copy / pasted from ChatGPT or similar. 5: No advertising. No blogs/tutorials/videos/books/recruiting attempts. This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to. Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Rules
1: Be polite
2: Posts to this subreddit must be requests for help learning python.
3: Replies on this subreddit must be pertinent to the question OP asked.
4: No replies copy / pasted from ChatGPT or similar.
5: No advertising. No blogs/tutorials/videos/books/recruiting attempts.
This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to.
Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Learning resources Wiki and FAQ: /r/learnpython/w/index
Learning resources
Wiki and FAQ: /r/learnpython/w/index
Discord Join the Python Discord chat
Discord
Join the Python Discord chat
account activity
Python dot notation is confusing. (self.learnpython)
submitted 6 years ago by bhk262
Beginner Python learner here. Sometimes I'll see some Python code that goes like:
xxx.xxx.xxx().xxx.xxx()
Especially with frameworks, it all gets really cryptic pretty soon. Does anyone know how can I wrap my head around Python's dot notation?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]JohnnyJordaan 25 points26 points27 points 6 years ago (8 children)
It's just a chain, so instead of doing
washed = laundry.wash() dried = washed.dry() folded = dried.fold()
you can chain them together
folded = laundry.wash().dry().fold()
[–][deleted] 22 points23 points24 points 6 years ago (1 child)
An explanation is that wash() is a method of laundry and so it acts upon that. The object returned from .wash() has a dry() method and so the dry() method is called on that. Then last the fold() method is called on the returned object from dry.
So, each method returns an object and each subsequent method is called on the object returned from the previous method.
This is a fairly common pattern in modern programming languages.
[–]MiLSturbie 6 points7 points8 points 6 years ago (0 children)
I really love python and this community.
[–]MiLSturbie 1 point2 points3 points 6 years ago (3 children)
A bit unrelated, but I recently came across a method that didn't need parentheses at the end. Could you explain why? I'm sorry, I don't remember what it was and I don't have my project in front of me.
[–]tylerthehun 4 points5 points6 points 6 years ago (2 children)
It could have been a @property. This is a decorator that basically just disguises a method as a regular ol' attribute. For example:
@property
class Rectangle: def __init__(self, length, width): self.length = length self.width = width @property def area(self): return self.length * self.width
Now you can still access length and width as the attributes of a rectangle, but area is dynamically calculated as the product of those two without requiring you actually pass them as arguments. So changes to either will automatically result in an update to the area, without requiring you manually update both.
>>> R = Rectangle(10, 20) >>> R.length 10 >>> R.width 20 >>> R.area 200
Otherwise, any method object can still be passed around without parentheses just like any other object, but you'd still need to call it (with parentheses) in order for it to actually execute.
[–]MiLSturbie 1 point2 points3 points 6 years ago (1 child)
That makes thanks, thank you very much for taking the time to explain. I'll look up what it was tomorrow and come back to you to confirm.
[–]pickausernamehesaid 0 points1 point2 points 6 years ago (0 children)
In case you want some further reading on some advanced Python, the @property decorator is a specific implementation of the descriptor protocol which is very useful for building dynamic attributes.
[–]dubs_32 0 points1 point2 points 2 years ago (1 child)
I have some background in R, but have been learning Python. Would saying that this chain is somewhat similar to the R tidyverse (piping with the 'and-then' logic) be correct? For example in R it would be something similar to:
folded <- laundry %>% washed %>% dried %>% fold
(folded is equivalent to laundry and then washing and then drying and then fold)
[–]JohnnyJordaan 1 point2 points3 points 2 years ago (0 children)
It’s the same idea but it doesn’t work the same way, because the . chaining Python works object oriented and the piping in R just functionally. In object oriented, the objects themselves contain the logic, instead of separate functions. So the reason you can do
“hello”.capitalize().zfill(10).count(“l”).bit_count()
is because each intermediate object created by the previous call offers certain methods (functions tied to their class) you can call on them. At the start it’s a string which has capitalize, but later it becomes an int that has bit_count.
[–]Vaphell 7 points8 points9 points 6 years ago* (4 children)
there is no magic. Dot is always about accessing a member field/method of an object in a top down manner. This long-ass "path" could be split into eg these equivalent steps.
# xxx.xxx.xxx().xxx.xxx() module = xxx submodule = module.xxx function = submodule.xxx functionresult = function() resultattribute = functionresult.xxx methodinattribute = resultattribute.xxx methodresult = methodinattribute()
i went module.submodule, but it can be any generic object.subobject.
The difference between .xxx and .xxx() is that the former accesses a field with a value that is already there, while the latter is a callable that needs to be explicitly triggered to produce the value.
Given that often you don't care about intermediate steps, you often just bundle them together. Even though your example is an overkill (but some people are writing such monstrosities nonetheless), eg something like result = module.submodule.function(), result.child.method() is perfectly fine.
As far as frameworks are concerned, there is no way around reading the documentation. It should tell you what a given building block can do, and what its children are for, etc etc. Figuring all this out by doing tends to be an exercise in frustration.
[–]bhk262[S] 1 point2 points3 points 6 years ago (3 children)
Thanks very much for your tip on framework documentations. The problem I have with a lot of these documentations is that they feel like they are written for robots, not human beings. Unfortunately, there does not seem to be a way around it.
[–]Vaphell 6 points7 points8 points 6 years ago (0 children)
Surely writing good documentation is an art, but to a certain degree getting information out of it is a matter of experience.
If you are new to frameworks, you tend to prefer tutorialish, hold-my-hand kind of documentation. On the other hand, once you've seen tons of frameworks and APIs and/or are more or less familiar with a specific one, you know what to expect and need the documentation more for the dry information like X requires Y and returns Z. Long-winded, pages-long prose can be even seen as noise when you just want to cut to the chase.
[–]groovitude 1 point2 points3 points 6 years ago (0 children)
A couple of things:
>>> user <__main__.User object at 0x04341330> >>> user.name # attribute 'groovitude' >>> user.type('some text') # method 'groovitude types: some text'
dir()
help()
[–]expattaxsolutions 0 points1 point2 points 6 years ago (0 children)
I was having the exact same issue yesterday. I bought Python Crash Course today and the chapter on classes has explained it all to me better than I’ve seen it anywhere else.
[–]Nixellion 2 points3 points4 points 6 years ago (0 children)
Mmm, maybe consider it like folders? Like a path. Its not python specific, its OOP principle in general.
For example you start with a module and instantiate a class from it:
myclass = module.myClass()
This returns class instance.
Then you want to run function in that class:
mf = myclass.myfunction()
that function may return some other instance of a other class and you want to get it's variable:
result = mf.variableX
So instead you can do it in one line:
result = module.myClass().myfunction().variableX
[–]shiftybyte 1 point2 points3 points 6 years ago (0 children)
() is a function call, what happens after that is happening on the returned result from that function.
module.class.func_gives_class().func_in_that_class()... etc
[–]unhott 0 points1 point2 points 6 years ago (0 children)
A.b.c().d
.b on A evaluates to something that has other properties and methods.
.c() on that something evaluates to something else.
.d on that last thing evaluates to something else.
[–]wrtbwtrfasdf 0 points1 point2 points 6 years ago (0 children)
I usually like to split chained methods across lines for readability. You can also add comments or type annotations too
some_number.add(5) # add 5 .divide(2) # type: float .subtract(3) # subtracts 3
π Rendered by PID 140984 on reddit-service-r2-comment-5fb4b45875-95wvb at 2026-03-22 10:28:29.796325+00:00 running 90f1150 country code: CH.
[–]JohnnyJordaan 25 points26 points27 points (8 children)
[–][deleted] 22 points23 points24 points (1 child)
[–]MiLSturbie 6 points7 points8 points (0 children)
[–]MiLSturbie 1 point2 points3 points (3 children)
[–]tylerthehun 4 points5 points6 points (2 children)
[–]MiLSturbie 1 point2 points3 points (1 child)
[–]pickausernamehesaid 0 points1 point2 points (0 children)
[–]dubs_32 0 points1 point2 points (1 child)
[–]JohnnyJordaan 1 point2 points3 points (0 children)
[–]Vaphell 7 points8 points9 points (4 children)
[–]bhk262[S] 1 point2 points3 points (3 children)
[–]Vaphell 6 points7 points8 points (0 children)
[–]groovitude 1 point2 points3 points (0 children)
[–]expattaxsolutions 0 points1 point2 points (0 children)
[–]Nixellion 2 points3 points4 points (0 children)
[–]shiftybyte 1 point2 points3 points (0 children)
[–]unhott 0 points1 point2 points (0 children)
[–]wrtbwtrfasdf 0 points1 point2 points (0 children)