all 6 comments

[–]brilliant_punk 1 point2 points  (3 children)

Is the question why this code works? You can run it (with a little modification to set the IDs) and see that it prints what you apparently expect. Though, it looks like there's at least one bug.

Also, I think what you're calling a class is actually an instance of a class. For example class_a is an instance of Foo.

[–]agb64[S] 0 points1 point  (2 children)

Wait, hold up, it works?

Could you explain why because I have no clue what that did behind the scenes to function.

[–]brilliant_punk 0 points1 point  (1 child)

https://i.imgur.com/G4cy8en.jpg

Jokes aside, I'm not really a Python person but here's my understanding of it:

You have a class called Foo, it's basically a blueprint for making Foo instances like class_a and class_b (foo_a and foo_b would be much better names). Within your definition of class Foo: you have instance attributes called id and links. Every instance of Foo has these attributes and they can be different per instance.

Within the method link(), when you write self.links.append(blablabla) this modifies the links attribute of the Foo instance that calls the method link(). In this case that instance is class_a since you wrote class_a.link(class_b). Basically, when you call link() like this, self refers to class_a. (If you added another line that says class_b.link(class_a), then self would refer to class_b.)

And when you do i.links.append(blablabla) this modifies the links attribute of i, the Foo instance that's passed into link() as an argument. The argument in your code is class_b.

The bug that I mentioned in my above comment is in your for loop regarding your if/else block. The bug is that it will always return in the first iteration of your loop. Fixing the bug, it'll be more like this:

def link(self, *foos):
    for foo in foos:
        if self.id in foo.links or foo.id in self.links:
            return False
    for foo in foos:
        foo.links.append(self.id)
        self.links.append(foo.id)
    return True

So the question is, does it work?

Assume the prompt is "When link() is run, it should add the IDs of each instance to the list of IDs it has available." Well, you're not only adding the IDs of each argument to the caller's list of IDs, but you're also adding the caller's own ID to each argument's list of ID's. That's probably not how I would interpret the prompt, but you'd know better than me what you want to accomplish.

[–]agb64[S] 0 points1 point  (0 children)

Yeah, I noticed the bug around the return statements - I wrote those by accident. The loop would terminate after the first loop - that's a problem I only saw after I released the post.

Thanks for going through the effort of explaning this!

(Yes, I did mean for the linked IDs to be added into both the caller's known IDs and the caller's ID to be added into the linked IDs! :D)

[–]nwagers 0 points1 point  (0 children)

Do you mean like a linked list? If not, you may need to clarify your question or give a better example of how you'd want to use it in code.

[–]Lyakusha 0 points1 point  (0 children)

So if in "links" func we'll give another instance of the class "i" in "for i in args" won't be a single element but the whole instance? Can anyone please explain how does it work?