Как протестировать, если атрибут класса является методом экземпляра

Похоже, что все ответы здесь до сих пор имеют одну или несколько из следующих проблем: (1) он может не работать на VC ++ (2) он требует дополнительных зависимостей, таких как boost или fmt (3), его слишком сложная пользовательская реализация и, вероятно, нет хорошо проверено.

Ниже приведен код для решения всех вышеперечисленных проблем.

#include 
#include 
#include 

std::string stringf(const char* format, ...)
{
    va_list args;
    va_start(args, format);
    #ifndef _MSC_VER

        //GCC generates warning for valid use of snprintf to get
        //size of result string. We suppress warning with below macro.
        #ifdef __GNUC__
        #pragma GCC diagnostic push
        #pragma GCC diagnostic ignored "-Wformat-nonliteral"
        #endif

        size_t size = std::snprintf(nullptr, 0, format, args) + 1; // Extra space for '\0'

        #ifdef __GNUC__
        # pragma GCC diagnostic pop
        #endif

        std::unique_ptr buf(new char[ size ] ); 
        std::vsnprintf(buf.get(), size, format, args);
        return std::string(buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
    #else
        int size = _vscprintf(format, args);
        std::string result(++size, 0);
        vsnprintf_s((char*)result.data(), size, _TRUNCATE, format, args);
        return result;
    #endif
    va_end(args);
}    

int main() {
    float f = 3.f;
    int i = 5;
    std::string s = "hello!";
    auto rs = stringf("i=%d, f=%f, s=%s", i, f, s.c_str());
    printf("%s", rs.c_str());
    return 0;
}

Примечания:

  1. Отдельная ветвь кода VC ++ необходима, потому что VC ++ решил отказаться от snprintf, который будет генерировать предупреждения компилятора для других ответов с высоким рейтингом выше. Поскольку я всегда работаю в режиме «предупреждения как ошибки», мне это не подходит.
  2. Функция принимает char * вместо std::string. Это потому, что большую часть времени эта функция вызывается с литеральной строкой, которая действительно char *, а не std::string. Если у вас есть std::string в качестве параметра формата, просто позвоните .c_str().
  3. Имя функции - stringf вместо таких вещей, как string_format для поддержки printf, scanf и т. Д.
  4. Это не решает проблему безопасности (то есть плохие параметры могут потенциально вызвать ошибку сегмента вместо исключения). Если вам это нужно, то лучше использовать библиотеки boost или fmt . Здесь я предпочитаю fmt, потому что это всего лишь один заголовок и исходный файл, который нужно добавить в проект, при этом синтаксис форматирования будет менее странным, чем boost. Однако оба они несовместимы со строками формата printf, поэтому ниже все равно полезно в этом случае.
  5. Код stringf проходит через компиляцию строгого режима GCC . Это требует дополнительных #pragma макросов для подавления ложных срабатываний в предупреждениях GCC.

Выше код был протестирован,

6
задан Richard Dorman 7 July 2009 в 09:34
поделиться

4 ответа

def hasmethod(obj, name):
    return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
14
ответ дан 8 December 2019 в 05:23
поделиться
import types

print isinstance(getattr(your_object, "your_attribute"), types.MethodType)
4
ответ дан 8 December 2019 в 05:23
поделиться

Вы можете использовать модуль inspect :

class A(object):
    def method_name(self):
        pass


import inspect

print inspect.ismethod(getattr(A, 'method_name')) # prints True
a = A()
print inspect.ismethod(getattr(a, 'method_name')) # prints True
3
ответ дан 8 December 2019 в 05:23
поделиться

Эта функция проверяет, существует ли атрибут, а затем проверяет, является ли атрибут методом с использованием модуля inspect .

import inspect

def ismethod(obj, name):
    if hasattr(obj, name):
        if inspect.ismethod(getattr(obj, name)):
            return True
    return False

class Foo:
    x = 0
    def bar(self):
        pass

foo = Foo()
print ismethod(foo, "spam")
print ismethod(foo, "x")
print ismethod(foo, "bar")
2
ответ дан 8 December 2019 в 05:23
поделиться
Другие вопросы по тегам:

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