Как перегрузиться __ init __ метод на основе типа аргумента?

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

297
задан martineau 12 February 2017 в 05:14
поделиться

6 ответов

Намного более опрятный способ получить 'альтернативных конструкторов' состоит в том, чтобы использовать classmethods. Например:

>>> class MyData:
...     def __init__(self, data):
...         "Initialize MyData from a sequence"
...         self.data = data
...     
...     @classmethod
...     def fromfilename(cls, filename):
...         "Initialize MyData from a file"
...         data = open(filename).readlines()
...         return cls(data)
...     
...     @classmethod
...     def fromdict(cls, datadict):
...         "Initialize MyData from a dict's items"
...         return cls(datadict.items())
... 
>>> MyData([1, 2, 3]).data
[1, 2, 3]
>>> MyData.fromfilename("/tmp/foobar").data
['foo\n', 'bar\n', 'baz\n']
>>> MyData.fromdict({"spam": "ham"}).data
[('spam', 'ham')]

причина, это более опрятно, состоит в том, что нет сомнения, что о том, какой тип ожидается, и Вы не вынуждены предположить то, что вызывающая сторона намеревалась для Вас сделать с типом данных, который это дало Вам. Проблема с isinstance(x, basestring) состоит в том, что нет никакого способа для вызывающей стороны сказать Вам, например, что даже при том, что тип не является basestring, необходимо рассматривать его как строку (и не другая последовательность.) И возможно вызывающая сторона хотела бы использовать тот же тип в различных целях, иногда как единственный объект, и иногда как последовательность объектов. Быть явным устраняет все сомнение и приводит к большему количеству устойчивого и более ясного кода.

409
ответ дан Thomas Wouters 23 November 2019 в 01:32
поделиться

Превосходный вопрос. Я занялся этой проблемой также, и в то время как я соглашаюсь, что "фабрики" (конструкторы метода класса) являются хорошим методом, я хотел бы предложить другого, которого я также нашел очень полезными:

Вот образец (это read, метод и не конструктор, но идея является тем же):

def read(self, str=None, filename=None, addr=0):
    """ Read binary data and return a store object. The data
        store is also saved in the interal 'data' attribute.

        The data can either be taken from a string (str 
        argument) or a file (provide a filename, which will 
        be read in binary mode). If both are provided, the str 
        will be used. If neither is provided, an ArgumentError 
        is raised.
    """
    if str is None:
        if filename is None:
            raise ArgumentError('Please supply a string or a filename')

        file = open(filename, 'rb')
        str = file.read()
        file.close()
    ...
    ... # rest of code

ключевая идея, здесь использует превосходную поддержку Python параметров, передаваемых по имени для реализации этого. Теперь, если я хочу считать данные из файла, я говорю:

obj.read(filename="blob.txt")

И считать его из строки, я говорю:

obj.read(str="\x34\x55")

Этот путь у пользователя есть просто отдельный метод звонить. Обработка его внутри, как Вы видели, не чрезмерно сложна

35
ответ дан FMc 23 November 2019 в 01:32
поделиться

Лучший путь состоял бы в том, чтобы использовать isinstance и преобразование типов. Если я понимаю Вас правильный, Вы хотите это:

def __init__ (self, filename):
    if isinstance (filename, basestring):
        # filename is a string
    else:
        # try to convert to a list
        self.path = list (filename)
8
ответ дан Justin 23 November 2019 в 01:32
поделиться

Необходимо использовать isinstance

isinstance(...)
    isinstance(object, class-or-type-or-tuple) -> bool

    Return whether an object is an instance of a class or of a subclass thereof.
    With a type as second argument, return whether that is the object's type.
    The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
    isinstance(x, A) or isinstance(x, B) or ... (etc.).
4
ответ дан Moe 23 November 2019 в 01:32
поделиться

Вы, вероятно, хотите isinstance встроенная функция:

self.data = data if isinstance(data, list) else self.parse(data)
2
ответ дан Eli Courtwright 23 November 2019 в 01:32
поделиться

Хорошо, большой. Я просто бросил вместе этот пример с кортежем, не имя файла, но это легко. Спасибо все.

class MyData:
    def __init__(self, data):
        self.myList = []
        if isinstance(data, tuple):
            for i in data:
                self.myList.append(i)
        else:
            self.myList = data

    def GetData(self):
        print self.myList

= [1,2]

b = (2,3)

c = MyData (a)

d = MyData (b)

c. GetData ()

d. GetData ()

[1, 2]

[2, 3]

-1
ответ дан Baltimark 23 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: