Today we'll take a look at some examples of object-oriented code in Python.
As I'm learning this topic almost in the same time I'm writing this, I'll do lot of mistakes - especially because some topics seem different than C++/Java/C# style I'm used to.
Ok, let's begin with creating a class with one method, creating an object of this class and calling this method.
We define a class ClassWithMethod, with one method: say_something(self) simply printing some text. self param is, as we will see, the reference to the calling object. For now, we just instantiate the class:
objectWithMethod = ClassWithMethod()
...and call the method:
objectWithMethod.say_something()
The result of running this code is:
Now let's define other class with one field (or attribute).
To instantiate and use it we can add the following lines to main function:
As we can see, __init__(self, name) works as a constructor with one parameter. The code now prints:
What about a method? Well, take a look at another class:
If we instantiate it, and set field name to something, we can call our method (in main!):
Giving result:
What's interesting, we can add fields to a class object on the fly, without declaring them. Add this to main:
We create another object (objectWithFieldAndMethod2), add the field named age to it (simply by initializing it) and then we can access it. The code execution result becomes:
Please note we've added the age field to our object, not class. It means that if we try to get to this field on our previous object, we get error.
...gives:
What about private fields? We define it by preceding initialized field name with double underscore:
We can create an object of this class and call the method to set field __name:
..but we can't do this:
... as the program will behave as such attribute doesn't exist:
BUT in fact, we can access this field - as "private" in Python does not mean the attribute is unaccesible - it rather means it should not be accessed. So we can access this attrbute using the following syntax: objectName._ClassName__field_name (please note the underscores, one before class name and two before field name):
This gives us:
Now let's take a look at a param passed in the constructor.
The following class:
...can be created like this:
We can then normally access the name field, so:
...gives us this ominous result:
The last thing: static (class) fields. They're defined simply in class body, not in the methods:
But beware: they can be accessed with both class name and object name. In the first case, they behave like static. In hte latter - they're simply fields, initialized with given value.
An example should give us more light on this:
... which code gives us:
We create two objects of class ClassWithStaticField, stat1 and stat2. Then we assign value 41 to the field field of the first object. It changes this instance's value, but the field field of object stat1 stays the same! What's more - the ClassWithStaticField.field is also another reference. We can change it, of course, by calling:
So the code:
results in:
Confusing? Well, for me it certainly is ;D The full program listing illustrating the concepts above looks as follows:
# !/usr/bin/python3 | |
class ClassWithMethod: | |
def say_something(self): | |
print("Elementary!") | |
class ClassWithField: | |
def __init__(self, name): | |
self.name = name | |
class ClassWithFieldAndMethod: | |
def tellName(self): | |
print(self.name) | |
class ClassWithPrivateFieldAndMethod: | |
def setName(self, name): | |
self.__name = name | |
class ClassWithParamaterInConstructor: | |
def __init__(self, name): | |
self.name = name | |
class ClassWithStaticField: | |
field = 40 | |
def someMethod(): | |
pass | |
def main(): | |
objectWithMethod = ClassWithMethod() | |
objectWithMethod.say_something() | |
objectWithField = ClassWithField("Lestrade") | |
print(objectWithField.name) | |
objectWithFieldAndMethod = ClassWithFieldAndMethod() | |
objectWithFieldAndMethod.name = "John Watson" | |
objectWithFieldAndMethod.tellName() | |
objectWithFieldAndMethod2 = ClassWithFieldAndMethod() | |
objectWithFieldAndMethod2.name = "Sherlock Holmes" | |
objectWithFieldAndMethod2.tellName() | |
# you can add field on the fly... | |
# ... to the object! | |
objectWithFieldAndMethod2.age = 33 | |
# you can do this only if field has been added: | |
print(objectWithFieldAndMethod2.age) | |
# this results in error! | |
#print(objectWithFieldAndMethod.age) | |
objectWithPrivateField = ClassWithPrivateFieldAndMethod() | |
objectWithPrivateField.setName("Mary Watson") | |
# you can not do this (error:) | |
#print(objectWithPrivateField.__name) | |
# but you can this: | |
print(objectWithPrivateField._ClassWithPrivateFieldAndMethod__name) | |
objectConstructedWithParam = ClassWithParamaterInConstructor("Moriarty") | |
print(objectConstructedWithParam.name) | |
stat1 = ClassWithStaticField() | |
stat2 = ClassWithStaticField() | |
stat2.field = 41 | |
print(stat1.field) # object's field default value is 40 | |
print(stat2.field) # this object's field value is 41 | |
print(stat1.field) # object's field default value is 40 | |
print(ClassWithStaticField.field) # static field value is still 40! | |
ClassWithStaticField.field = 42 | |
print(ClassWithStaticField.field) # not anymore! | |
if __name__ == "__main__": | |
main() |
... and gives the following result:
I hope it happens to be useful for some of you :)
No comments:
Post a Comment