OO (Python)

Uit De Vliegende Brigade
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Naar navigatie springen Naar zoeken springen

Python is een object oriented programmeertaal. Hoe werkt dat ook al weer?

Een string is een object

>>> mijnobject = "hallo"   # Gewoon een string initialiseren
>>> print(mijnobject)      # En afdrukken. Nix schokkends
hallo

>>> print(mijnobject.upper())   # upper() is een method/attribuut van deze string!
MIJNOBJECT

>>> mijnobject   # Nu krijg je enige informatie over het betreffende object
'hallo'          # Voor een string is dat dus blijkbaar die string, binnen enkele haakjes

Klasses

  • De class of klasse van een object, is de definitie, blauwdruk, sjabloon of template om nieuwe exemplaren van dat object te instantiëren. De klasse-aanroep geschiedt hier impliciet - Simpelweg door de string te instantiëren
  • Algemener: Een klasse is de definitie van een verzameling samenhangende gegevens en functies [1].

Met type() kun je de klasse van een object achterhalen. Een string is een object van de klasse 'str':

>>> print(type(mijnobject))
<class 'str'>

Attributen & methods

Hierboven zie je de aanroep print(mijnobject.upper()). Ik zou denken dat dat een method is, oftewel een functie die bij een object hoort. Dit voorbeeld geeft echter aan, dat dit een attribuut betreft:

>>> print 'myobject'.mijnfantasieding()
AttributeError: 'str' object has no attribute 'mijnfantasieding'

Ik denk dat het 't beste is, als ik me niet al te druk maak om dat onderscheid :)

Alle methods achterhalen

Tjakka:

>>> dir(mijnobject)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Voorbeelden:

>>> print(mijnobject.isprintable)
<built-in method isprintable of str object at 0x7f1bbf3eafb8>   # Zonder () achter de method, krijg je alleen info *over* de methode/attribuut

>>> print(mijnobject.isprintable())   # Method of property? Misschien maakt het niet uit
True

>>> print(len(mijnobject))   # Geem method, maar een 'externe' functie!
5

Methodes vs attributen - Nog een keer

Mbv. Beautiful Soup heb ik een pagina opgeslagen in object page_soup. Met dir(page_soup) krijg ik:

['ASCII_SPACES', 'DEFAULT_BUILDER_FEATURES', 'NO_PARSER_SPECIFIED_WARNING', 'ROOT_TAG_NAME', '__bool__', '__call__', '__class__', '__contains__', '__copy__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_all_strings', '_check_markup_is_url', '_feed', '_find_all', '_find_one', '_is_xml', '_lastRecursiveChild', '_last_descendant', '_linkage_fixer', '_most_recent_element', '_namespaces', '_popToTag', '_should_pretty_print', 'append', 'attrs', 'builder', 'can_be_empty_element', 'cdata_list_attributes', 'childGenerator', 'children', 'clear', 'contains_replacement_characters', 'contents', 'currentTag', 'current_data', 'declared_html_encoding', 'decode', 'decode_contents', 'decompose', 'descendants', 'encode', 'encode_contents', 'endData', 'extend', 'extract', 'fetchNextSiblings', 'fetchParents', 'fetchPrevious', 'fetchPreviousSiblings', 'find', 'findAll', 'findAllNext', 'findAllPrevious', 'findChild', 'findChildren', 'findNext', 'findNextSibling', 'findNextSiblings', 'findParent', 'findParents', 'findPrevious', 'findPreviousSibling', 'findPreviousSiblings', 'find_all', 'find_all_next', 'find_all_previous', 'find_next', 'find_next_sibling', 'find_next_siblings', 'find_parent', 'find_parents', 'find_previous', 'find_previous_sibling', 'find_previous_siblings', 'format_string', 'formatter_for_name', 'get', 'getText', 'get_attribute_list', 'get_text', 'handle_data', 'handle_endtag', 'handle_starttag', 'has_attr', 'has_key', 'hidden', 'index', 'insert', 'insert_after', 'insert_before', 'isSelfClosing', 'is_empty_element', 'is_xml', 'known_xml', 'markup', 'name', 'namespace', 'new_string', 'new_tag', 'next', 'nextGenerator', 'nextSibling', 'nextSiblingGenerator', 'next_element', 'next_elements', 'next_sibling', 'next_siblings', 'object_was_parsed', 'original_encoding', 'parent', 'parentGenerator', 'parents', 'parse_only', 'parserClass', 'parser_class', 'popTag', 'prefix', 'preserve_whitespace_tag_stack', 'preserve_whitespace_tags', 'prettify', 'previous', 'previousGenerator', 'previousSibling', 'previousSiblingGenerator', 'previous_element', 'previous_elements', 'previous_sibling', 'previous_siblings', 'pushTag', 'recursiveChildGenerator', 'renderContents', 'replaceWith', 'replaceWithChildren', 'replace_with', 'replace_with_children', 'reset', 'select', 'select_one', 'setup', 'smooth', 'string', 'strings', 'stripped_strings', 'tagStack', 'text', 'unwrap', 'wrap']

en met commando

page_soup.h1

krijg ik

<h1 class="page-title-text">"graphics card"</h1>

.

Echter, h1 wordt niet genoemd in de lijst met dir → Het is een attribuut en geen methode → Laat het los!

Mijn eerste klasse

#! /usr/bin/python3
#
##############################################################################

class Foo:
    "Here is an explanation about the foo class"

    def helloworld(self): # A method is a function within a class
    	print ("Hello, world! - Greetings from foo")

    def bye_world(self):
    	print ("Bye, world! - Greetings from foo")

    def setx(self, x):   # x is a member 
    	self.x =x

    def printx(self):
    	print (self.x)

    def reset_x(self):
    	self.x=0

    def inc_x(self):
    	self.x=self.x+1


##############################################################################
# Example 1 - All worked as expected
##############################################################################
#
# f=Foo()
# f.helloworld()
# f.bye_world()
# f.setx(12)
# f.printx()
# f.reset_x()
# f.printx()
# f.inc_x()
# f.printx()
# f.inc_x()
# f.printx()


##############################################################################
# You can't print an object that isn't initiated yet:
##############################################################################
#
# Error: 'Foo' object has no attribute 'x'
##########################################
#
# f=Foo()
# f.printx()

# OK
##########################################
#
f=Foo()
f.reset_x()
f.printx()

Klasses, Init & variabelen

Voorbeeld van initialization of init:

#! /usr/bin/python3
#
##############################################################################

class Foo:
    "Here is an explanation about the foo class"

    def __init__(self):
        print("The world is an instance of Foo richer!")
        self.x=0   # Init var x + set to 0


##############################################################################
# __init__
##############################################################################
#
f=Foo()
print(f.x)

Output:

The world is an instance of Foo richer!
0

Als de regel met self.x=0 wordt uit-gecommentariseerd, krijg je als output:

The world is an instance of Foo richer!
Traceback (most recent call last):
  File "./klasse-03.py", line 36, in <module>
    print(f.x)
AttributeError: 'Foo' object has no attribute 'x'

Interessant: Het script wordt wel uitgevoerd tot aan het probleem.

Delete a member - Dictionary

#! /usr/bin/python3
#
##############################################################################

class Foo:
    "Here is an explanation about the foo class"

    def helloworld(self):
    	print ("Hello, world! - Greetings from foo")

    def bye_world(self):
    	print ("Bye, world! - Greetings from foo")

    def setx(self, x):
    	self.x =x

    def printx(self):
    	print (self.x)

    def reset_x(self):
    	self.x=0

    def inc_x(self):
    	self.x=self.x+1


##############################################################################
# Delete a member
##############################################################################
#
# Je kunt een member (=een variabele van een object) verwijderen. Deze code 
# geeft daarom foutmelding AttributeError: 'Foo' object has no attribute 'x'
#
# f=Foo()
# f.reset_x()
# del f.x
# f.printx()

##############################################################################
# Dictionary
##############################################################################
#
f=Foo()
f.reset_x()
f.inc_x()
f.printx()

vars(f)		# Gebeurt nix
#f.vars()	# No such attribute

Ik ben tot hiero gekomen

https://en.wikibooks.org/wiki/Python_Programming/Classes#Dynamic_Class_Structure

Bronnen