как сказать, что переменная повторяема, но не строка

Короткий ответ с блокнотом до точного размера

'#'+((1<<24)*(Math.random()+1)|0).toString(16).substr(1)

74
задан priestc 28 June 2009 в 17:45
поделиться

3 ответа

Используйте isinstance (я не понимаю, почему это плохая практика)

import types
if not isinstance(arg, types.StringTypes):

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

С другой стороны, это также работает для производных строковых классов.

class MyString(str):
    pass

isinstance(MyString("  "), types.StringTypes) # true

Кроме того, вы можете захотеть взглянуть на этот предыдущий вопрос .

Ура.


NB: поведение изменено в Python 3, поскольку StringTypes и basestring больше не определены. В зависимости от ваших потребностей, вы можете заменить их в isinstance на str , Как упоминал @Theron Luhn , вы также можете использовать six .

44
ответ дан 24 November 2019 в 12:03
поделиться

Как вы правильно заметили, отдельная строка - это последовательность символов.

Итак, вам действительно нужно выяснить, что за последовательность arg используется isinstance или type (a) == str.

Если вы хотите реализовать функцию, которая принимает переменное количество параметров, вы должны сделать это следующим образом:

def function(*args):
    # args is a tuple
    for arg in args:
        do_something(arg)

function ("ff") and function ( «ff», «ff») будет работать.

Я не вижу сценария, в котором требуется функция isiterable (), подобная вашей. Плохой стиль - не isinstance (), а ситуации, когда вам нужно использовать isinstance ().

1
ответ дан 24 November 2019 в 12:03
поделиться

Начиная с Python 2.6, с введением абстрактных базовых классов, isinstance (используемый в ABC, а не в конкретных классах) теперь считается вполне приемлемым. В частности:

from abc import ABCMeta, abstractmethod

class NonStringIterable:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is NonStringIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

Это точная копия (изменяет только имя класса) Iterable , как определено в _abcoll.py (деталь реализации collections.py ]) ... причина, по которой это работает так, как вы хотите, в то время как collections.Iterable нет, заключается в том, что последний делает все возможное, чтобы гарантировать, что строки считаются повторяемыми, путем вызова Iterable.register (str) явно сразу после этого оператора class .

Конечно, это '

16
ответ дан 24 November 2019 в 12:03
поделиться
Другие вопросы по тегам:

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