From b32230f7ec23e659624bc8010988199fc5d2fe06 Mon Sep 17 00:00:00 2001 From: Mark Pilgrim Date: Mon, 8 Jun 2009 21:46:14 -0400 Subject: [PATCH] more dfn --- special-method-names.html | 212 +++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/special-method-names.html b/special-method-names.html index 87e5650..447abeb 100644 --- a/special-method-names.html +++ b/special-method-names.html @@ -45,23 +45,23 @@ td a:link, td a:visited{border:0} ① to initialize an instance x = MyClass() -x.__init__() +x.__init__() ② the “official” representation as a string -repr(x) -x.__repr__() +repr(x) +x.__repr__() ③ the “informal” value as a string -str(x) -x.__str__() +str(x) +x.__str__() ④ the “informal” value as a byte array -bytes(x) -x.__bytes__() +bytes(x) +x.__bytes__() ⑤ the value as a formatted string format(x) -x.__format__(format_spec) +x.__format__(format_spec)
  1. The __init__() method is called after the instance is created. If you want to control the actual creation process, use the __new__() method. @@ -82,16 +82,16 @@ td a:link, td a:visited{border:0} And Python Calls… ① to iterate through a sequence -iter(seq) -seq.__iter__() +iter(seq) +seq.__iter__() ② to get the next value from an iterator -next(seq) -seq.__next__() +next(seq) +seq.__next__() ③ to create an iterator in reverse order -reversed(seq) -seq.__reversed__() +reversed(seq) +seq.__reversed__()
    1. The __iter__() method is called whenever you create a new iterator. It’s a good place to initialize the iterator with initial values. @@ -111,23 +111,23 @@ td a:link, td a:visited{border:0} ① to get a computed attribute (unconditionally) x.my_property -x.__getattribute__('my_property') +x.__getattribute__('my_property') ② to get a computed attribute (fallback) x.my_property -x.__getattr__('my_property') +x.__getattr__('my_property') ③ to set an attribute x.my_property = value -x.__setattr__('my_property', value) +x.__setattr__('my_property', value) ④ to delete an attribute del x.my_property -x.__delattr__('my_property') +x.__delattr__('my_property') ⑤ to list all attributes and methods dir(x) -x.__dir__() +x.__dir__()
      1. If your class defines a __getattribute__() method, Python will call it on every reference to any attribute or method name (except special method names, since that would cause an unpleasant infinite loop). @@ -217,10 +217,10 @@ AttributeError to “call” an instance like a function my_instance() -my_instance.__call__() +my_instance.__call__() -

        The zipfile module uses this to define a class that can decrypt an encrypted zip file with a given password. The zip decryption algorithm requires you to store state during decryption. Defining the decryptor as a class allows you to maintain this state within a single instance of the decryptor class. The state is initialized in the __init__() method and updated as the file is decrypted. But since the class is also “callable” like a function, you can pass the instance as the first argument of the map() function, like so: +

        The zipfile module uses this to define a class that can decrypt an encrypted zip file with a given password. The zip decryption algorithm requires you to store state during decryption. Defining the decryptor as a class allows you to maintain this state within a single instance of the decryptor class. The state is initialized in the __init__() method and updated as the file is decrypted. But since the class is also “callable” like a function, you can pass the instance as the first argument of the map() function, like so:

        # excerpt from zipfile.py
         class _ZipDecrypter:
        @@ -264,12 +264,12 @@ bytes = zef_file.read(12)
         And Python Calls…
         
         the length of a sequence
        -len(seq)
        -seq.__len__()
        +len(seq)
        +seq.__len__()
         
         to know whether a sequence contains a specific value
         x in seq
        -seq.__contains__(x)
        +seq.__contains__(x)
         
         
         

        The cgi module uses these methods in its FieldStorage class, which represents all of the form fields or query parameters submitted to a dynamic web page. @@ -311,19 +311,19 @@ class FieldStorage: to get a value by its key x[key] -x.__getitem__('key') +x.__getitem__('key') to set a value by its key x[key] = value -x.__setitem__('key', value) +x.__setitem__('key', value) to delete a key-value pair del x[key] -x.__delitem__('key') +x.__delitem__('key') to provide a default value for missing keys x[nonexistent_key] -x.__missing__('nonexistent_key') +x.__missing__('nonexistent_key')

        The FieldStorage class from the cgi module also defines these special methods, which means you can do things like this: @@ -358,7 +358,7 @@ class FieldStorage:

        Classes That Act Like Numbers

        -

        Using the appropriate special methods, you can define your own classes that act like numbers. That is, you can add them, subtract them, and perform other mathematical operations on them. This is how fractions are implemented — the Fraction class implements these special methods, then you can do things like this: +

        Using the appropriate special methods, you can define your own classes that act like numbers. That is, you can add them, subtract them, and perform other mathematical operations on them. This is how fractions are implemented — the Fraction class implements these special methods, then you can do things like this:

         >>> from fractions import Fraction
        @@ -376,55 +376,55 @@ class FieldStorage:
         
         addition
         x + y
        -x.__add__(y)
        +x.__add__(y)
         
         subtraction
         x - y
        -x.__sub__(y)
        +x.__sub__(y)
         
         multiplication
         x * y
        -x.__mul__(y)
        +x.__mul__(y)
         
         division
         x / y
        -x.__truediv__(y)
        +x.__truediv__(y)
         
         floor division
         x // y
        -x.__floordiv__(y)
        +x.__floordiv__(y)
         
         modulo (remainder)
         x % y
        -x.__mod__(y)
        +x.__mod__(y)
         
         floor division & modulo
         divmod(x, y)
        -x.__divmod__(y)
        +x.__divmod__(y)
         
         raise to power
         x ** y
        -x.__pow__(y)
        +x.__pow__(y)
         
         left bit-shift
         x << y
        -x.__lshift__(y)
        +x.__lshift__(y)
         
         right bit-shift
         x >> y
        -x.__rshift__(y)
        +x.__rshift__(y)
         
         bitwise and
         x & y
        -x.__and__(y)
        +x.__and__(y)
         
         bitwise xor
         x ^ y
        -x.__xor__(y)
        +x.__xor__(y)
         
         bitwise or
         x | y
        -x.__or__(y)
        +x.__or__(y)
         
         
         

        That’s all well and good if x is an instance of a class that implements those methods. But what if it doesn’t implement one of them? Or worse, what if it implements it, but it can’t handle certain kinds of arguments? For example: @@ -454,55 +454,55 @@ class FieldStorage: addition x + y -y.__radd__(x) +y.__radd__(x) subtraction x - y -y.__rsub__(x) +y.__rsub__(x) multiplication x * y -y.__rmul__(x) +y.__rmul__(x) division x / y -y.__rtruediv__(x) +y.__rtruediv__(x) floor division x // y -y.__rfloordiv__(x) +y.__rfloordiv__(x) modulo (remainder) x % y -y.__rmod__(x) +y.__rmod__(x) floor division & modulo divmod(x, y) -y.__rdivmod__(x) +y.__rdivmod__(x) raise to power x ** y -y.__rpow__(x) +y.__rpow__(x) left bit-shift x << y -y.__rlshift__(x) +y.__rlshift__(x) right bit-shift x >> y -y.__rrshift__(x) +y.__rrshift__(x) bitwise and x & y -y.__rand__(x) +y.__rand__(x) bitwise xor x ^ y -y.__rxor__(x) +y.__rxor__(x) bitwise or x | y -y.__ror__(x) +y.__ror__(x)

        But wait! There’s more! If you’re doing “in-place” operations, like x /= 3, there are even more special methods you can define. @@ -515,51 +515,51 @@ class FieldStorage: in-place addition x += y -x.__iadd__(y) +x.__iadd__(y) in-place subtraction x -= y -x.__isub__(y) +x.__isub__(y) in-place multiplication x *= y -x.__imul__(y) +x.__imul__(y) in-place division x /= y -x.__itruediv__(y) +x.__itruediv__(y) in-place floor division x //= y -x.__ifloordiv__(y) +x.__ifloordiv__(y) in-place modulo x %= y -x.__imod__(y) +x.__imod__(y) in-place raise to power x **= y -x.__ipow__(y) +x.__ipow__(y) in-place left bit-shift x <<= y -x.__ilshift__(y) +x.__ilshift__(y) in-place right bit-shift x >>= y -x.__irshift__(y) +x.__irshift__(y) in-place bitwise and x &= y -x.__iand__(y) +x.__iand__(y) in-place bitwise xor x ^= y -x.__ixor__(y) +x.__ixor__(y) in-place bitwise or x |= y -x.__ior__(y) +x.__ior__(y)

        Note: for the most part, the in-place operation methods are not required. If you don’t define an in-place method for a particular operation, Python will try the methods. For example, to execute the expression x /= y, Python will: @@ -582,55 +582,55 @@ class FieldStorage: negative number -x -x.__neg__() +x.__neg__() positive number +x -x.__pos__() +x.__pos__() absolute value abs(x) -x.__abs__() +x.__abs__() inverse ~x -x.__invert__() +x.__invert__() complex number complex(x) -x.__complex__() +x.__complex__() integer int(x) -x.__int__() +x.__int__() floating point number float(x) -x.__float__() +x.__float__() number rounded to nearest integer round(x) -x.__round__() +x.__round__() number rounded to nearest n digits round(x, n) -x.__round__(n) +x.__round__(n) smallest integer >= x math.ceil(x) -x.__ceil__() +x.__ceil__() largest integer <= x math.floor(x) -x.__floor__() +x.__floor__() truncate x to nearest integer toward 0 math.trunc(x) -x.__trunc__() +x.__trunc__() PEP 357 number as a list index a_list[x] -x.__index__() +x.__index__()

        Classes That Can Be Compared

        @@ -645,31 +645,31 @@ class FieldStorage: equality x == y -x.__eq__(y) +x.__eq__(y) inequality x != y -x.__ne__(y) +x.__ne__(y) less than x < y -x.__lt__(y) +x.__lt__(y) less than or equal to x <= y -x.__le__(y) +x.__le__(y) greater than x > y -x.__gt__(y) +x.__gt__(y) greater than or equal to x >= y -x.__ge__(y) +x.__ge__(y) truth value in a boolean context if x: -x.__bool__() +x.__bool__()

        Classes That Can Be Serialized

        @@ -685,31 +685,31 @@ class FieldStorage: a custom object copy copy.copy(x) -x.__copy__() +x.__copy__() a custom object deepcopy copy.deepcopy(x) -x.__deepcopy__() +x.__deepcopy__() to get an object’s state before pickling pickle.dump(x, file) -x.__getstate__() +x.__getstate__() to serialize an object pickle.dump(x, file) -x.__reduce__() +x.__reduce__() to serialize an object (new pickling protocol) pickle.dump(x, file, protocol_version) -x.__reduce_ex__(protocol_version) +x.__reduce_ex__(protocol_version) control over how an object is created during unpickling x = pickle.load(file) -x.__getnewargs__() +x.__getnewargs__() to restore an object’s state after unpickling x = pickle.load(file) -x.__setstate__() +x.__setstate__()

        Classes That Can Be Used in a with Block

        @@ -726,11 +726,11 @@ class FieldStorage: do something special when entering a with block with x: -x.__enter__() +x.__enter__() do something special when leaving a with block with x: -x.__exit__() +x.__exit__()

        This is how the [FIXME-xref] with file idiom works. @@ -775,43 +775,43 @@ def __exit__(self, *args) -> None: a class constructor x = MyClass() -x.__new__() +x.__new__() a class destructor del x -x.__del__() +x.__del__() only a specific set of attributes to be defined -x.__slots__() +x.__slots__() a custom hash value hash(x) -x.__hash__() +x.__hash__() to get an attribute’s value x.color -type(x).__dict__['color'].__get__(x, type(x)) +type(x).__dict__['color'].__get__(x, type(x)) to set an attribute’s value x.color = 'PapayaWhip' -type(x).__dict__['color'].__set__(x, 'PapayaWhip') +type(x).__dict__['color'].__set__(x, 'PapayaWhip') to delete an attribute del x.color -type(x).__dict__['color'].__del__(x) +type(x).__dict__['color'].__del__(x) to control whether an object is an instance of your class isinstance(x, MyClass) -MyClass.__instancecheck__(x) +MyClass.__instancecheck__(x) to control whether a class is a subclass of your class issubclass(C, MyClass) -MyClass.__subclasscheck__(C) +MyClass.__subclasscheck__(C) to control whether a class is a subclass of your abstract base class issubclass(C, MyABC) -MyABC.__subclasshook__(C) +MyABC.__subclasshook__(C)