OO (Python): verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
 
(6 tussenliggende versies door dezelfde gebruiker niet weergegeven)
Regel 1: Regel 1:
 
Python is een ''object oriented'' programmeertaal. Hoe werkt dat ook al weer?
 
Python is een ''object oriented'' programmeertaal. Hoe werkt dat ook al weer?
  
== Voorbeeld: Zelfs een string is een object ==
+
== Een string is een object ==
  
 
<pre>
 
<pre>
>>> mijnobject = "hallo"
+
>>> mijnobject = "hallo"   # Gewoon een string initialiseren
>>> print mijnobject
+
>>> print(mijnobject)      # En afdrukken. Nix schokkends
 
hallo
 
hallo
  
>>> print 'mijnobject'.upper()
+
>>> print(mijnobject.upper())  # upper() is een method/attribuut van deze string!
 
MIJNOBJECT
 
MIJNOBJECT
 +
 +
>>> mijnobject  # Nu krijg je enige informatie over het betreffende object
 +
'hallo'          # Voor een string is dat dus blijkbaar die string, binnen enkele haakjes
 
</pre>
 
</pre>
  
Regel 15: Regel 18:
  
 
* 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
 
* 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 defintie van een verzameling samenhangende gegevens en functies [https://en.wikibooks.org/wiki/Python_Programming/Classes].
+
* Algemener: Een ''klasse'' is de definitie van een verzameling samenhangende gegevens en functies [https://en.wikibooks.org/wiki/Python_Programming/Classes].
 +
 
 +
Met <code>type()</code> kun je de klasse van een object achterhalen. Een string is een object van de klasse 'str':
 +
 
 +
<pre>
 +
>>> print(type(mijnobject))
 +
<class 'str'>
 +
</pre>
  
 
=== Attributen & methods ===
 
=== Attributen & methods ===
  
Hierboven zie je de aanroep <code>print 'mijnobject'.upper()</code>. Ik zou denken dat dat een ''method'' is, oftewel een ''functie die bij een object hoort''. Het voorbeeld hieronder geeft echter aan, dat dit een ''attribuut'' betreft. Ik denk dat het 't beste is, als ik me daar niet al te druk om maak:
+
Hierboven zie je de aanroep <code>print(mijnobject.upper())</code>. 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:
  
 
<pre>
 
<pre>
Regel 25: Regel 35:
 
AttributeError: 'str' object has no attribute 'mijnfantasieding'
 
AttributeError: 'str' object has no attribute 'mijnfantasieding'
 
</pre>
 
</pre>
 +
 +
Ik denk dat het 't beste is, als ik me niet al te druk maak om dat onderscheid :)
  
 
=== Alle methods achterhalen ===
 
=== Alle methods achterhalen ===
Regel 38: Regel 50:
  
 
<pre>
 
<pre>
>>> mijnobject.isprintable
+
>>> print(mijnobject.isprintable)
<built-in method isprintable of str object at 0x7f1bbf3eafb8>
+
<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
 
</pre>
 
</pre>
 +
 +
=== Methodes vs attributen - Nog een keer ===
 +
 +
Mbv. ''Beautiful Soup'' heb ik een pagina opgeslagen in object ''page_soup''. Met <code>dir(page_soup)</code> krijg ik:
 +
 +
<pre>
 +
['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']
 +
</pre>
 +
 +
en met commando
 +
 +
page_soup.h1
 +
 +
krijg ik <pre><h1 class="page-title-text">"graphics card"</h1></pre>.
 +
 +
Echter, <code>h1</code> wordt niet genoemd in de lijst met <code>dir</code> → Het is een attribuut en geen methode → Laat het los!
  
 
== Mijn eerste klasse ==
 
== Mijn eerste klasse ==

Huidige versie van 31 jul 2019 om 19:03

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