Recently I've been using python as part of my job. I've become quite familiar with the language if I should say so myself, and I actually like the language a lot. Although it is a bit hard to shift between Python and languages like C# and Java, because I mix up the syntax and sometimes forget that C# needs curly brackets and python needs indentation. However, I usually get used to it after at couple of minutes.
I've heard many people say that Python is a good language for learners, because it is easy to understand and you are forced to have a readable code style (Because indentation that is enforced to form blocks etc.). For me (as a programmer for a couple of years) it was quite easy to learn the language (I think it took me about 30 mins reading a quick tutorial to understand the basic syntax in the language). So in the end I agree that it is a quite nice and easy-to-learn language.
Now to the fun part of this blog post: Funny aspects that I think is making Python a hard language to understand and use. In my experience with Python I've run into a couple of things that I think is a bit strange, or to speak in a more professional manner, quite different from most languages I know.
Let's take an example class written in C#.
1 2 3 4 5 6 7 8 | class TestClass { public string Test { get; set; } public void Test() { Console.WriteLine("test function"); } } |
Here we have a class definition with a property called Test and a method called Test. It should be noted that this is not legal in C#! The problem is that there will be an error on the Test method as the class already contains a definition for Test.
However the following is actually legal in Python (3).
1 2 3 4 5 6 7 8 9 | class TestClass(): test = "test" def test(self): print("test method") var1 = TestClass() # Create a new instance of TestClass var1.test() # Prints "test method" print(var1.test) # Prints <bound method TestClass.test of <__main__.TestClass object at {hex value}>> |
What happens here is that the variable test is actually never used. The output of the call to var1.test() should be logical. The "confusing" part is that the variable test is actually replaced by the method definition (as it is written after the variable declaration) and the print will print out information about the method
Interesting!!! This means that we can replace variables at runtime with methods! But it also means that we can replace methods with vars at runtime - and we can do it from within the method itself! Let me show you how in the following example.
1 2 3 4 5 6 7 8 | class TestClass(): def test(self): print("test method") self.test = "test" var1 = TestClass() #Make an instance. var1.test() #Prints out "test method" print(var1.test) #Prints "test" |
As we can do this, it also means that we can actually break our own code at runtime! If we were to do the following we will end up with a runtime error!
1 2 3 4 5 6 7 8 | class TestClass(): def test(self): print("test method") self.test = "test" var1 = TestClass() #Make an instance. var1.test() #Prints out "test method" var1.test() #TypeError: 'str' object is not callable |
As the test method is replaced by the test variable in the first call to var1.test() we can no longer call the test method, as the string type is not callable (as the TypeError says). I think this is an example of where Python is confusing and gets a bit hard to debug, because I think new programmers will be confused because the syntax is not illegal, there is no warning, and it is at runtime we find out this is actually wrong, and will produce an error. Also the logical flow of what you think happens (in most languages) is not the same and therefore can be hard to debug.
Another funny thing about Python that I haven't seen before is that Python class variables is actually both static and instance variables. So we can actually do the following
1 2 3 4 5 6 7 8 | class TestClass2: test = "TestStatic" t = TestClass2() print(t.test) #Prints "TestStatic" t.test = "TestInstance" #Set an instance variable named test print(TestClass2.test) #Prints "TestStatic" print(t.test) #Prints "TestInstance" |
This can also be a bit confusing for learners, however this makes much sense if you are an experienced programmer, as you know you can replace variable values, however it is still a bit weird that you can use variables as both static and non-static variables, but you have no way of defining variables to be static or not in python, and this is just a language choice.
So in the end I still agree that Python is a really nice and easy-to-learn language. However, the language also have some strange choices but whenever you know them it's not that hard to get used to.
Feel free to try out the examples! All of them can be run in python3.4 ( except for the C# example of cause ). You can also run them in python2.7 as long as you change the print(something something) to print something something
Happy coding out there!
- Archi