Arjan, just recently discovered your channel, and I can't say enough about what a pleasure it is to watch your videos. Incredibly well done. Always something to learn. Keep up the great work, my friend. Cheers, Steve
I have paid 3000€ for Python Crash Course and I have terrible lector for desing patterns module. Your videos are sooooo good and much better then my lecturer, that I felt ashamed to watch them just for free while paying him.
Arjan, please never ever stop making videos. You're going to help me get through my software engineering program! Great videos, clean, perfect length, structured and very good examples!
You used to say Python in this british way iirc. Today you said it with a more North American sound to it. This seems logical to me, as your accent sounds more american in most pronunciations than British. Nice one! (I'm a language and accent coach trying to switch into SWE).
Been coding in python form 3 years like now and I need to say that your channel rocks ;) I dare to say it's the best python channel on current yt. Keep it going man, you;re doing great job! :)
I am trying to improve my python coding and your videos are just what I needed. Great presentations, coding examples and the time length is just perfect. Kudos to you!! Cheers!!
Found your channel a few weeks ago and I'm now starting to watch your design pattern videos and have shared it with a friend who also loves it. You do amazing content please keep it up, thanks for sharing your knowledge with everyone
@@ArjanCodes actually you don't need abstract classes in python, because python always calculates what function to call in the runtime. that's kind of the whole point of duck typing idea: any method can become an "interface", without any keywords or code acrobatics. that is also why inheritance is used so rarely in python.
Thank Arjan for the video. But we could move further with this example. from abc import ABC, abstractmethod class Switchable2(ABC): @abstractmethod def switch(self) -> 'Switchable2': pass class OffLightBulk(Switchable2): def switch(self) -> 'OnLightBulk': print('Turn on the light bulk.') return OnLightBulk() class OnLightBulk(Switchable2): def switch(self) -> 'OffLightBulk': print('Turn off the light bulk.') return OffLightBulk() class App2(): def __init__(self, c: Switchable2): self.client = c def press(self): self.client = self.client.switch() offlightbulk = OffLightBulk() app = App2(offlightbulk) app.press() app.press()
Would you be able to add a video that explains a difference between Dependency Inversion, Strategy and Factory patterns. They look pretty similar to me. Especially if you could put it in the context of the data science. Love the video, btw.
Thank you Arjan :) I wish you all the success. I am a full-stack dev mostly working with Python nowadays and your videos are really helpful to me. Exactly the content I was looking for.
Dude, you don't get enough views/subscriptions for the level of content your are delivering! Amazing explanations. Thank you so much for doing this. Do you know any automation tools to verify dependencies and check code quality?
Kind of late for the party but this was an amazing video. I really like your attention to detail while explaining this topics with ease. Looking forward to more in this series. Thanks for the amazing content Sincerely A new sub
great videos man, it sucks that you don't have that many subs rn, but keep going! you have a cohesive teaching style, and coupled with python (my most comfortable language, personally ofc) its pretty effective!
Thank you so much! About the nr of subs: TH-cam is a long game, and I've only started about half a year ago. So, I'm pretty happy with the number of subscribers actually.
Awesome video! Perfect pacing. Really enjoyed learning how to improve my skills. I'm going to binge the rest of this video series. Keep up the good work 👏 😁
I'm now getting into Python and I've been enjoying watching your videos. I have a question. I get that removing the dependency of the lightswitch class from the electricity class is good and that it reduces coupling which should make for more reusable code, but then you're making a lot of classes based on the abstract base class of Switchable. Now, if Switchable needs to be updated, so does every single class that depends on it. So, isn't this a shifting of problems and not a removal of them? Why is using abstract base classes the preferred method here? Please help me understand this better. Thanks and hopefully talk to you soon.
Great video.I had one question regarding this. Although we have decoupled the ElecticPowerSwitch class, but this results in high coupling between the classes which are inheriting from the Switchable class such as LightBulb and Fan class. So if any change is defined in the Switchable class, the same needs to be implemented in the derived classes, otherwise this will throw an error. Is this by design, and if not then what can we do to remove coupling there.
Thanks! In an ideal world, you'd have code without any coupling at all. Unfortunately that is not practical because code uses other code. Basically what ABCs such as Switchable help you do is define the exact way coupling happens. The result of using a class like Switchable is that ElectricPowerSwitch is no longer directly coupled to Fan or LightBulb and can work with anything that adheres to Switchable. It does show how important it is to make sure the abstract classes you use to define what the coupling looks like are well-designed. Indeed, any change in the Switchable class would lead to changes in the derived class. If you design them well though, you don't need to change abstract classes all that often in my experience because they mainly define what concepts look like, and concepts don't change very often.
Good stuff man. Been watching your videos lately. I have a question. Since the bulb is on, and the switch is flipped, would I flip a flag in the bulb to say it was on, so if I checked the bulb I can tell without looking for a switch, and if I looked for a switch to turn off the bulb, should it have reference to the switch, so the switch flips (by going to switch it points at to perform the switch). Too much magic?
Thank you for your efforts to help people write better code. But I would appreciate if you give an example of inconvenience that could happen if we do not use the ABC. My modest abilities are not allowing me to understand abstract issues like "dependency" when I am not presented with a concrete example of problem that is particularly caused by dependency. I cannot see in the code refactoring you presented how does the dependency disappear (if I understand the word correctly). I think the chain of dependency just got elongated instead of being cut. The ElectricPowerSwitch requires its clients to be Switchable instead of particularly being a LightBulb, but in order to be equipped with a switch, the LightBulb class has imperatively to inherit from Switchable and there is no other way around. So the LightBulb is dependent of the requirement of the ElectricPowerSwitch anyway. This kind of dependency has nothing to do with implementation, it is an inherent property of the very subject we are dealing with, and that we cannot get rid of. The benefit that I see from using this refactoring is the isolation of the characteristic of switchability from the LightBulb in order to reuse it for other things; which maybe what you meant. But if there is something else I did not grasp, I would like that you enlighten me please.
Amazing video! One question, instead of defining 'on' inside ElectricPowerSwitch, can we define 'on' for the Fan and the LightBulb? Does the below code follow correct practices? class ElectricalAppliance(ABC): @abstractmethod def turn_on(self): self.on = True @abstractmethod def turn_off(self): self.on = False class Fan(ElectricalAppliance): def turn_on(self): super().turn_on() print("Fan: turned on...") def turn_off(self): super().turn_off() print("Fan: turned off...") class ElectricPowerSwitch: def __init__(self, appliance: ElectricalAppliance): self.appliance = appliance self.appliance.on = False def press(self): if self.appliance.on: self.appliance.turn_off() else: self.appliance.turn_on()
@Aadithya Varma you can not do this as it's an abstract method and implementation is always handled by child classes to make it more flexible. There could be a possibility to add some logic before setting on=True for some Appliance if you do that in ElectricalAppliance then it may create an issue and the purpose of abstraction loses.
Hi @ArjanCodes Thank you for the video. I like your videos, they are straight to the point. I have a doubt on dependency inversion. What is the point of having - class Switchable(ABC) apart from a developer forgets to implement an abstract method. and A small change in ElectricPowerSwitch __init__ self.lightBulb = l -> self.client = l will decouple without implementing an interface. so can you please tell how is Switchable still be useful ? And can you please make a video on duck typing without telling anything that walks and quacks a duck is duck. I am not a native English speaker. I tried to understand the concept of duck typing like a thousand time. But I am still confused.
Arjan, it seems to me that Switchable should/could(?) be an interface, not an abstract class. Is it true that to implement interfaces in Python it's better to use Protocols? Or maybe Mixins? Again, I have a strange gut feeling that a protocol in Python is exactly what an interface is in C#, for instance... Thanks.
I wish you'd explain the most important thing, namely, how is it fan or lightbulb gets instantiated if switchable turn on/off has pass inside a method..? Is c: Switchable acting as a placeholder or a default value in the absence of a class...? And when you pass on the class like a fan it gets instantiated..? Simple yet confusing
When to use it? I can't simply add contracts/abstraction to any class. I guess the only reason is when you need to add another alike class. Then you refactor the whole structure.
Another reason to do this is if you want to make your code easier to test. By using dependency inversion, you have more control over what other objects are used, and you can inject them with mocks when you write your tests.
Dependency Invertion = keep doing programming by contract. It's heavier in terms of coding and conception, but flexibility is beeing maximized. Use interfaces, abstract classes are not required as far as a concrete implementation can implement an interface without extending an abstract implementation (do all languages provide this mecanism ?). Depending on how many concrete implementations you will have of interfaces (at least 2), abstract classes will become necessary in order to match recommended patterns. So, dependency inversion is an annoying term who just says "use interfaces".
I agree that interfaces are a pretty good solution for dependency inversion (I use them all the time when I write Typescript code). Unfortunately, Python doesn't have interfaces, so we're stuck with ABCs.
Beginner question. Taking simple project up a notch I'm trying to separate strategies from creatures and I'm lost. Imagine files structure like `/mygame/strategies/voice/{abstract_voice,meow,quack,talk}.py` alongside of `/mygame/creatures/{abstract_creature,cat,duck,human}.py`. I want to type hint `AbstractVoice` in a `@voice_strategy.setter` of `AbstractCreature` but how do I introduce this composition in a sensible manner? How do I make the duck quack, so to speak? If I add `from mygame.strategies.voice import AbstractVoice` in `creatures/abstract_creature.py` I can't re-use creatures + strategies in a package with a different name because this is literally a named package import. But if I replace this with a relative import I get "attempted relative import beyond top level package" when e.g. trying to test just the sub-package. I tried that with and without `__init__.py` files. Python is unintuitive mess whenever I try to do anything slightly more complicated than following tutorials.
It’s important to consider what you define as a package. A package is supposed to be something that you can take out your system and reuse somewhere else. If you have creatures with voices, and they rely on each other (which is the case in your example), then don’t put them in separate packages because you will only be able to use them together. Have you tried asking your question in the Discord server (discord.ArjanCodes.com)? There’s a few very knowledgeable folks there who have worked with big Python software projects who can surely help you out.
Why not just use standard inheritance to inherit from a parent class whose methods all just raise NotImplementedError ? Is this just so IDE's can identify that the interface is not satisfied at build time? Can type hints recognize regular inheritance? i.e. if you specify that a variable is of a given type, will mypy complain if you pass in an instance of a subclass of that type?
Maybe this example is too simple for me to really see the benefit of this. Here we could remove the Switchable class, remove the type hint from the Power Switch and we would be fine. 1. Code is shorter. 2. Another developer does not need to understand what ABC is. Essentially what the Switchable class does is it changes the error message if we forgot to implement turn_on or turn_off methods and we are able to hint the type which we could do in the comments instead. Do I understand this correctly or am I missing something?
SOLID principles aren't actually strictly orthogonal so a lot of examples of one principle can be also used as examples of some of the other ones. But in this case I don't think this is an example of the Liskov substitution principle. This is clearly a dependency inversion. Liskov principle is not about "use abstract classes and inheritence". Quite the opposite, Liskov principle is about the cases where it seems as a good idea to use inheritence but it's NOT! The most typical example of disobeying the Liskov principle is to make a Square class to be a subclass of a Rectangle class.
For some more general advice about how to create software faster, this video might interest you as well: th-cam.com/video/MU20ah5s9ww/w-d-xo.html
Very clean videos. I wish I had these 5 years ago. I haven't seen these concepts explained this clean and simple.
Thank you, Nate, I’m happy you are enjoying it.
Thank you for producing this type of material. Most of the Python videos, tutorials and online classes are too basic. Double thumbs up!
Thank you so much! Glad that you liked it.
I absolutely love how chill you are while explaining
Where have u been X years ago. I like these videos and push everyone in my company to watch.
I really appreciate the support, Valentyn! I'm happy to hear my content has been useful to you (and hopefully others in your company ahah).
Your videos are by far the best Python tutorials I've found
Thank you so much, glad you like them!
It may seem simple, but I really appreciate when you zoom into the code. Great explanation.
Im really happy that Ive found your channel. There are many developers that needs to be educated in these subjects
Thanks Mateus, I'm happy you like the content!
Another fantastic video, thank you very much. Seen the "abc" module a few times but never knew it stood for "Abstract Base Class".
Thanks so much Daniel!
Arjan, just recently discovered your channel, and I can't say enough about what a pleasure it is to watch your videos. Incredibly well done. Always something to learn. Keep up the great work, my friend. Cheers, Steve
Thanks so much Steve, I'm glad you enjoy the videos!
I have paid 3000€ for Python Crash Course and I have terrible lector for desing patterns module. Your videos are sooooo good and much better then my lecturer, that I felt ashamed to watch them just for free while paying him.
Thanks Petr, happy you’re enjoying the content and found it informational!
Arjan, please never ever stop making videos. You're going to help me get through my software engineering program!
Great videos, clean, perfect length, structured and very good examples!
Thanks Max, glad you like the videos. And I have no plans at all to stop ;).
A lightbulb just turned on in my head. Great content. Keep it going Arjan!
Will do! And glad it helped you.
I don't know someone who explained better than this !!
Very well explained! Now I want to understand the difference between dependency injection vs dependency inversion
Great suggestion, I have put it in my list.
You used to say Python in this british way iirc. Today you said it with a more North American sound to it. This seems logical to me, as your accent sounds more american in most pronunciations than British. Nice one!
(I'm a language and accent coach trying to switch into SWE).
Been coding in python form 3 years like now and I need to say that your channel rocks ;) I dare to say it's the best python channel on current yt. Keep it going man, you;re doing great job! :)
WOW This is amazing! I'm a newbie programmer. Thanks for creating this series. I'm going to watch them all!
Glad you like them!
I’m primarily a TS and PHP user, but love this channel! So useful no matter which OOP language one uses, I think. 🙏🏻
Glad to hear you like it!
I am trying to improve my python coding and your videos are just what I needed. Great presentations, coding examples and the time length is just perfect. Kudos to you!! Cheers!!
Thank you so much, Miguel! Glad you like the videos!
Found your channel a few weeks ago and I'm now starting to watch your design pattern videos and have shared it with a friend who also loves it.
You do amazing content please keep it up, thanks for sharing your knowledge with everyone
Thanks James, Glad you liked the videos and the content is helpful.
Great explanation. I can't believe you have
That's really kind, thank you! I'm glad you are enjoying the video.
@@ArjanCodes actually you don't need abstract classes in python, because python always calculates what function to call in the runtime. that's kind of the whole point of duck typing idea: any method can become an "interface", without any keywords or code acrobatics. that is also why inheritance is used so rarely in python.
Thank Arjan for the video. But we could move further with this example.
from abc import ABC, abstractmethod
class Switchable2(ABC):
@abstractmethod
def switch(self) -> 'Switchable2':
pass
class OffLightBulk(Switchable2):
def switch(self) -> 'OnLightBulk':
print('Turn on the light bulk.')
return OnLightBulk()
class OnLightBulk(Switchable2):
def switch(self) -> 'OffLightBulk':
print('Turn off the light bulk.')
return OffLightBulk()
class App2():
def __init__(self, c: Switchable2):
self.client = c
def press(self):
self.client = self.client.switch()
offlightbulk = OffLightBulk()
app = App2(offlightbulk)
app.press()
app.press()
Would you be able to add a video that explains a difference between Dependency Inversion, Strategy and Factory patterns. They look pretty similar to me. Especially if you could put it in the context of the data science. Love the video, btw.
Thanks , happy you’re enjoying the content!
And Thanks for the suggestions, I've put it on the list.
Amazing explanation. I was having a really bad time trying to implement DIP with a language different from Java.
Thank you, Andrés, happy the video helped you.
Amazing contents, just discovered your channel and my confidence with code increased 100x.
Amazing!
Excellent explanation with an easy example! Thanks Arjan.
Glad you liked it
Something you might not hear from your partner: I love it when you talk code. Really, I do!
Great example on the ABC module. Thanks
Keep the videos coming.
Thank you Arjan :) I wish you all the success. I am a full-stack dev mostly working with Python nowadays and your videos are really helpful to me. Exactly the content I was looking for.
Great tips for Python programmers. Cheers.
Thank you Kamil, glad you liked the video!
Dude, you don't get enough views/subscriptions for the level of content your are delivering! Amazing explanations. Thank you so much for doing this. Do you know any automation tools to verify dependencies and check code quality?
dependency inversion is most important principle for write reusable code. python must have it built in
Very nice channel. I shared it with my python teammates.
Kind of late for the party but this was an amazing video. I really like your attention to detail while explaining this topics with ease. Looking forward to more in this series. Thanks for the amazing content
Sincerely
A new sub
Thank you Newascap, happy you’re enjoying the video!
The quality of this series of videos is very good, very helpful for writing programs, hope you can keep going, and be seen by more people : )
Glad you like them!
@@ArjanCodes Very very good explanations
very clear and crisp tips.. got here via linkedin : )
Thank you! Happy you are enjoying it :)
great videos man, it sucks that you don't have that many subs rn, but keep going!
you have a cohesive teaching style, and coupled with python (my most comfortable language, personally ofc) its pretty effective!
Thank you so much! About the nr of subs: TH-cam is a long game, and I've only started about half a year ago. So, I'm pretty happy with the number of subscribers actually.
You've helped so much; your videos are amazing!
Thank you so much!
I must be a switchable cause I also get turned on and turned off. Good codes Arjan
thanks, perfectly clear explanation!
Thanks for this tutorial. It was quite explanatory
Glad you liked it, Jude Leon!
Great Video. Can you please zoom in your IDE a little bit for next videos? It'll be a great help. Thanks
Thanks! If you watch my more recent videos, this should be a lot better.
Absolutely amazing videos, well thought examples & perfect length videos!
Thank you Lalit, glad you liked the video!
Awesome video! Perfect pacing. Really enjoyed learning how to improve my skills. I'm going to binge the rest of this video series. Keep up the good work 👏 😁
Oh thats how you use it, thanks!
Nice work. Could you cover SOLID fully?
Absolutely, I have a few other things in the pipeline at the moment, but covering SOLID will definitely happen in the future.
great explanation. thanks ! much easier than I thought.
Great to hear!
That was VERY helpful!! Thank you!
I'm happy you enjoyed the video!
I'm now getting into Python and I've been enjoying watching your videos. I have a question. I get that removing the dependency of the lightswitch class from the electricity class is good and that it reduces coupling which should make for more reusable code, but then you're making a lot of classes based on the abstract base class of Switchable. Now, if Switchable needs to be updated, so does every single class that depends on it. So, isn't this a shifting of problems and not a removal of them? Why is using abstract base classes the preferred method here? Please help me understand this better. Thanks and hopefully talk to you soon.
Nice video!
Maybe you could have talked about duck typing?
Very good explanation, thanks!
Thank you Bobbly, glad you enjoyed it!
Great video.I had one question regarding this. Although we have decoupled the ElecticPowerSwitch class, but this results in high coupling between the classes which are inheriting from the Switchable class such as LightBulb and Fan class. So if any change is defined in the Switchable class, the same needs to be implemented in the derived classes, otherwise this will throw an error. Is this by design, and if not then what can we do to remove coupling there.
Thanks! In an ideal world, you'd have code without any coupling at all. Unfortunately that is not practical because code uses other code. Basically what ABCs such as Switchable help you do is define the exact way coupling happens. The result of using a class like Switchable is that ElectricPowerSwitch is no longer directly coupled to Fan or LightBulb and can work with anything that adheres to Switchable.
It does show how important it is to make sure the abstract classes you use to define what the coupling looks like are well-designed. Indeed, any change in the Switchable class would lead to changes in the derived class. If you design them well though, you don't need to change abstract classes all that often in my experience because they mainly define what concepts look like, and concepts don't change very often.
@@ArjanCodes well said
Thank you very much !! It's a very interesting video!
Glad you liked it!
great video, the best explanation I saw!!!!
Thank you Guillermo!
Excellent videos and explanations! You earned a subscriber
Awesome, thank you!
Simply awesome 👌 , keep making such content
Good stuff man. Been watching your videos lately. I have a question.
Since the bulb is on, and the switch is flipped, would I flip a flag in the bulb to say it was on, so if I checked the bulb I can tell without looking for a switch, and if I looked for a switch to turn off the bulb, should it have reference to the switch, so the switch flips (by going to switch it points at to perform the switch).
Too much magic?
Another awesome video. Thank you!
Thank you Michael, I’m happy the videos are helpful to you..
Informative as always.. Thank you very much :)
My pleasure!
Thank you for your efforts to help people write better code.
But I would appreciate if you give an example of inconvenience that could happen if we do not use the ABC. My modest abilities are not allowing me to understand abstract issues like "dependency" when I am not presented with a concrete example of problem that is particularly caused by dependency.
I cannot see in the code refactoring you presented how does the dependency disappear (if I understand the word correctly). I think the chain of dependency just got elongated instead of being cut. The ElectricPowerSwitch requires its clients to be Switchable instead of particularly being a LightBulb, but in order to be equipped with a switch, the LightBulb class has imperatively to inherit from Switchable and there is no other way around. So the LightBulb is dependent of the requirement of the ElectricPowerSwitch anyway. This kind of dependency has nothing to do with implementation, it is an inherent property of the very subject we are dealing with, and that we cannot get rid of.
The benefit that I see from using this refactoring is the isolation of the characteristic of switchability from the LightBulb in order to reuse it for other things; which maybe what you meant. But if there is something else I did not grasp, I would like that you enlighten me please.
This is amazing! Keep up the good work!
Thank you, will do! :)
Thank you for this breakdown!
Glad it was helpful!
Your videos are just amazing.
Thank you Renato, glad you like them!
Amazing video! One question, instead of defining 'on' inside ElectricPowerSwitch, can we define 'on' for the Fan and the LightBulb?
Does the below code follow correct practices?
class ElectricalAppliance(ABC):
@abstractmethod
def turn_on(self):
self.on = True
@abstractmethod
def turn_off(self):
self.on = False
class Fan(ElectricalAppliance):
def turn_on(self):
super().turn_on()
print("Fan: turned on...")
def turn_off(self):
super().turn_off()
print("Fan: turned off...")
class ElectricPowerSwitch:
def __init__(self, appliance: ElectricalAppliance):
self.appliance = appliance
self.appliance.on = False
def press(self):
if self.appliance.on:
self.appliance.turn_off()
else:
self.appliance.turn_on()
@Aadithya Varma you can not do this as it's an abstract method and implementation is always handled by child classes to make it more flexible. There could be a possibility to add some logic before setting on=True for some Appliance if you do that in ElectricalAppliance then it may create an issue and the purpose of abstraction loses.
@@subhampolpagedar203 That makes sense. Thanks for this insight!
Nice one but one thing i want from the very beggining of your video is more zoom in whenever you explain any codebase.
Thank you- it's fixed in more recent videos!
Subscribed! Keep Going dude.
Thanks man!
Nice example!
Thank you César!
Very clear, thanks a lot !
Glad you liked it!
really good videos!! it would be awesome if you could keep them a bit shorter
Thank you! You'll notice that in my more recent videos, I've worked on removing some of the fluff and making the videos a bit shorter.
Amazing video
from abc import ABC, abstractmethod
class Switchable(ABC): # abstract class
@abstractmethod
def turn_on(self):
pass
@abstractmethod
def turn_off(self):
pass
class LightBulb(Switchable): # inheritance
def turn_on(self):
print("On")
def turn_off(self):
print("Off")
class Fan(Switchable): # more objects can be connected and switched.
def turn_on(self):
print("On")
def turn_off(self):
print("Off")
class ElectricPowerSwitch:
def __init__(self, c: Switchable): # dependency inversion
self.client = c
self.on = False
def press(self):
if self.on:
self.client.turn_off()
self.on = False
else:
self.client.turn_on()
self.on = True
l = LightBulb()
f = Fan()
switch = ElectricPowerSwitch(f) # independent
switch.press()
switch.press()
switch.press()
Is there a way to look at the source code that defines the abc module? I'd be interested in how ABC and @abstractmethod are defined in Python.
I like the way you explain with Keep going 💪💪
Thank you Muhamed, glad you like it & will do!
Again, very clear. Thanks
Thank you very much Youcef!
This hurts my old brain, so in this case can we just remove class lightbulb all together then? I like simple stuff.
It would definitely be more simple, but also a lot darker ;).
@@ArjanCodes nice pun
Hi @ArjanCodes
Thank you for the video. I like your videos, they are straight to the point.
I have a doubt on dependency inversion.
What is the point of having - class Switchable(ABC) apart from a developer forgets to implement an abstract method.
and A small change in ElectricPowerSwitch __init__
self.lightBulb = l -> self.client = l will decouple without implementing an interface.
so can you please tell how is Switchable still be useful ?
And can you please make a video on duck typing without telling anything that walks and quacks a duck is duck.
I am not a native English speaker. I tried to understand the concept of duck typing like a thousand time. But I am still confused.
genuine question: would it be more cohesive if the bool "on" is declared in the abstract class?
Thanks, this is sooooooooooo usefull
Thank you! Happy you’re enjoying the videos!
If not for others keep making this stuff for me atleast.
Will do 👍🏻
Great content. Keep it up.
Thanks, will do!
How do you recommend doin dependency injection in python?
interesting! but would be more clear if you started without passing the lightbulb in the cosntructor, and showed the actual ioc
Indeed! I've done a few more videos about this topic in the mean time to better show the inversion of control.
Man you are really awesome. Thanks a lot.
You're welcome!
Arjan, it seems to me that Switchable should/could(?) be an interface, not an abstract class. Is it true that to implement interfaces in Python it's better to use Protocols? Or maybe Mixins? Again, I have a strange gut feeling that a protocol in Python is exactly what an interface is in C#, for instance... Thanks.
Wonderful !
Thank you so much!
I wish you'd explain the most important thing, namely, how is it fan or lightbulb gets instantiated if switchable turn on/off has pass inside a method..? Is c: Switchable acting as a placeholder or a default value in the absence of a class...? And when you pass on the class like a fan it gets instantiated..? Simple yet confusing
Great videos - Thanks! :)
Glad you liked it!
great video
Thank you!
would it be correct to say that switchable is a base class with virtual functions turn_on() and turn_off.
This is the terms used in c++ i believe.
When to use it? I can't simply add contracts/abstraction to any class.
I guess the only reason is when you need to add another alike class. Then you refactor the whole structure.
Another reason to do this is if you want to make your code easier to test. By using dependency inversion, you have more control over what other objects are used, and you can inject them with mocks when you write your tests.
Dependency Invertion = keep doing programming by contract. It's heavier in terms of coding and conception, but flexibility is beeing maximized. Use interfaces, abstract classes are not required as far as a concrete implementation can implement an interface without extending an abstract implementation (do all languages provide this mecanism ?). Depending on how many concrete implementations you will have of interfaces (at least 2), abstract classes will become necessary in order to match recommended patterns. So, dependency inversion is an annoying term who just says "use interfaces".
I agree that interfaces are a pretty good solution for dependency inversion (I use them all the time when I write Typescript code). Unfortunately, Python doesn't have interfaces, so we're stuck with ABCs.
Mimicking can replace when done well :)
Beginner question. Taking simple project up a notch I'm trying to separate strategies from creatures and I'm lost. Imagine files structure like `/mygame/strategies/voice/{abstract_voice,meow,quack,talk}.py` alongside of `/mygame/creatures/{abstract_creature,cat,duck,human}.py`. I want to type hint `AbstractVoice` in a `@voice_strategy.setter` of `AbstractCreature` but how do I introduce this composition in a sensible manner? How do I make the duck quack, so to speak? If I add `from mygame.strategies.voice import AbstractVoice` in `creatures/abstract_creature.py` I can't re-use creatures + strategies in a package with a different name because this is literally a named package import. But if I replace this with a relative import I get "attempted relative import beyond top level package" when e.g. trying to test just the sub-package. I tried that with and without `__init__.py` files. Python is unintuitive mess whenever I try to do anything slightly more complicated than following tutorials.
It’s important to consider what you define as a package. A package is supposed to be something that you can take out your system and reuse somewhere else. If you have creatures with voices, and they rely on each other (which is the case in your example), then don’t put them in separate packages because you will only be able to use them together. Have you tried asking your question in the Discord server (discord.ArjanCodes.com)? There’s a few very knowledgeable folks there who have worked with big Python software projects who can surely help you out.
@@ArjanCodes Wasn't aware of the Discord. Will ask there, although, you've already cleared it a bit. :) Thanks!
I miss an autofac container and service collection / provider in python.
Why not just use standard inheritance to inherit from a parent class whose methods all just raise NotImplementedError ?
Is this just so IDE's can identify that the interface is not satisfied at build time? Can type hints recognize regular inheritance? i.e. if you specify that a variable is of a given type, will mypy complain if you pass in an instance of a subclass of that type?
Maybe this example is too simple for me to really see the benefit of this. Here we could remove the Switchable class, remove the type hint from the Power Switch and we would be fine. 1. Code is shorter. 2. Another developer does not need to understand what ABC is. Essentially what the Switchable class does is it changes the error message if we forgot to implement turn_on or turn_off methods and we are able to hint the type which we could do in the comments instead. Do I understand this correctly or am I missing something?
Great video, but I wouldn’t call this dependency inversion, it’s an example of Liskov substitution principle.
SOLID principles aren't actually strictly orthogonal so a lot of examples of one principle can be also used as examples of some of the other ones. But in this case I don't think this is an example of the Liskov substitution principle. This is clearly a dependency inversion. Liskov principle is not about "use abstract classes and inheritence". Quite the opposite, Liskov principle is about the cases where it seems as a good idea to use inheritence but it's NOT! The most typical example of disobeying the Liskov principle is to make a Square class to be a subclass of a Rectangle class.
Isn't this just default behaviour with python duck typing? Anything that implements turn_on() and turn_off() quacks like a switchable, right?
Indeed, and then you could make Switchable a Protocol class. I'll cover that in more detail in a future video.
thanks a lot ! : D
Thanks so much Muntean, glad you liked it!
anyone got an id on that sweatshirt he's wearing 😬
and thanks for the awesome videos!