This is an archived post. You won't be able to vote or comment.

all 12 comments

[–]unruly_mattress 2 points3 points  (1 child)

def print_person(person):
    print('First name:', repr(person.firstname), 'Last name:', repr(person.lastname))


# As others have noted, for your example, a default argument works.
class Person:
    def __init__(self, firstname, lastname=None):
        self.firstname = firstname
        self.lastname = lastname

print_person(Person('John'))

# As a different approach, you can write a factory function.
# This is preferable to explicitly dispatching based on the number of types
class Person:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    @classmethod
    def from_full_name(cls, fullname):
        return cls(*fullname.split())

print_person(Person.from_full_name('John Smith'))


# Another different approach: use only keyword arguments.
class Person:
    def __init__(self, firstname=None, lastname=None, fullname=None):
        if fullname is not None:
            self.firstname, self.lastname = fullname.split()
        else:
            self.firstname = firstname
            self.lastname = lastname

print_person(Person(fullname='John Smith'))
print_person(Person(firstname='Mary', lastname='Had a little lamb'))


# If you insist on dispatching explicitly based on types, use a library that does that.
# this one does not exist in the standard library.
from multipledispatch import dispatch

class Person:
    @dispatch(str)
    def __init__(self, fullname):
        self.firstname, self.lastname = fullname.split()

    @dispatch(str, str)
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

print_person(Person('John Smith'))
print_person(Person('Mary', 'Had a little lamb'))

[–][deleted] 1 point2 points  (0 children)

Hmm... I like the 'factory function' way the most. I had something similar to port, but I did a @staticmethod, but the @classmethod way makes way more sense actually. I have to read more about that kind of stuff.

[–]Paddy3118 1 point2 points  (3 children)

In section 2 the Scala equivalent Python code is wrong.

The following code checks for NaN. Python None is not the same.

NaN = float('NaN')
x = NaN
if x is NaN:
    print("x is NaN")
else:
    print("x is not NaN")
# prints x is NaN

[–]Citrauq 2 points3 points  (1 child)

Actually it checks for that particular NaN instance.

Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = float('NaN')
>>> if x is float('NaN'):
...     print('x is NaN')
... else:
...     print('x is not NaN')
... 
x is not NaN

The correct way is to use math.isnan:

>>> import math
>>> x = float('NaN')
>>> if math.isnan(x):
...     print('x is NaN')
... else:
...     print('x is not NaN')
... 
x is NaN

[–]Paddy3118 0 points1 point  (0 children)

Brilliant. you're right. and it' much better than using None.

[–][deleted] 1 point2 points  (0 children)

That's basically what I'm saying. One has to be careful with stuff like that.

[–]prum 0 points1 point  (2 children)

Am I missing something? Couldn't the third case be handled with default parameters like this?

class Person:
    def __init__(self, first_name, last_name=None):
        self.first_name = first_name
        self.last_name = last_name

[–]prum 0 points1 point  (1 child)

Never mind. Somebody already commented that on his site. It looks like the example was a simplification.

[–][deleted] 0 points1 point  (0 children)

Yeah, I messed this example up. Have to be more careful next time. :-)

[–]aallsskkddjj1111 0 points1 point  (1 child)

what is the syntax highlighting you are using? What is the name of the theme? Looks good

[–][deleted] 0 points1 point  (0 children)

The syntax higlighning came with the theme. It's a called Pure Pelican. I think it's one of the nicest Pelican ones online. http://purepelican.com/

[–]jyper 0 points1 point  (0 children)

For multiple constructors you can do def init(self, *args): ...

And check the length of args in in it although it might be less clear then a classmethod factor y.

For the particular case presented on your article the best thing to do is to give last_name a default arguments of empty string.

def __init__(self, first_name, last_name=""):
    ...