views:

106

answers:

6

I have a class A that can be generated from two different ways.

  • a = A(path_to_xml_file)
  • a = A(listA, listB)

The first method has file path as an input to parse from XML file to get listA, and listB. The second method is given two lists.

I can think of two ways to implement multiple constructor. What do you think? What method normally Python guys use for this case?

Check the type

class A():
    def __init__(self, arg1, arg2 = None):
        if isinstance(arg1, str): 
            ...
        elif isinstance(arg1, list):
            ...

a = A("abc")
b = A([1,2,3],[4,5,6])

Make different builders

class A2():
    def __init__(self):
        pass
    def genFromPath(self, path):
        ...
    def genFromList(self, list1, list2):
        ...
a = A2()
a.genFromPath("abc")
b = A2()
b.genFromList([1,2,3],[4,5,6])
+7  A: 

Make the constructor take the two lists. Write a factory classmethod that parses the XML and returns the object.

Ignacio Vazquez-Abrams
+2  A: 

Looking at the problem more closely, I'd suggest having the class take two lists, and include a helper function in the module:

class A(object):
    def __init__(self, list1, list2):
        # Init from lists here
        pass

def create_A_from_path(path):
    list1, list2 = parse_xml_into_lists(path)
    return A(list1, list2)
Chris B.
+2  A: 

Use classmethod for second one

class A(object):
    @classmethod
    def from_string(cls, string):
        # ...

    @classmethod
    def from_lists(cls, list1, list2):
        # ...

Use module's functions

def from_string(string):
    # ...

def from_lists(list1, list2):
    # ...

class A(object):
    pass
petraszd
A: 

i don't know exactly what you are implementing there but in my first look i can see that you are not following the Single Responsibility Principle ;

The same class read from a file to do some stuff and the same class get two list and do something .

if this something is the same so good , i will suggest what other have told you before create another method or function to handle the file but don't put them in the same method _ init _ .

if not create a new class for handling your file.

singularity
please , why -1 we are here to learn so please put a comment if you see something wrong , thanks
singularity
+2  A: 

Since the number of arguments passed to the initializer is different in each case, you can avoid type-checking by using the extended call syntax:

class A(object):
    def __init__(self, *args):
        if len(args) == 1:
            path = args[0]
            ...
        elif len(args) == 2:
            list1 = args[0]
            list2 = args[1]
            ...
        else:
            raise SomeException()

Ray
Note that this is not really a good method since it goes against Python's usually self-documenting nature.
Ignacio Vazquez-Abrams
Looks pretty obvious to me...
martineau
+1  A: 
class A(object):
    @staticmethod
    def from_string(str):
        obj =A()
        obj.str = str
        return obj

    @staticmethod
    def from_list(lis):
        obj = A()
        obj.lis = lis
        return obj

>>>
(obj1, obj2) = A.from_string('hello'), A.from_list(['one', 'two'])
Dantalion