Find Out Whether a C++ Object Is Callable

How can I tell if a class has a method `__call__`?

myc.__call__ is giving you the __call__ method used to call myc itself, not instances of myc. It's the method invoked when you do

new_myc_instance = myc()

not when you do

new_myc_instance()

__call__ in myc.__dict__ gives you a NameError because you forgot to put quotation marks around __call__, and if you'd remembered to put quotation marks, it would have given you False because myc.__call__ isn't found through myc.__dict__. It's found through type(myc).__dict__ (a.k.a. type.__dict__, because type(myc) is type).


To check if myc has a __call__ implementation for its instances, you could perform a manual MRO search, but collections.abc.Callable already implements that for you:

issubclass(myc, collections.abc.Callable)

How can I check if an object is of a certain type at runtime in C#?

You can use the is keyword. For example:

using System; 

class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;

Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" : "not ") );
Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" : "not ") );
}

static bool IsInteger( object obj )
{
if( obj is int || obj is long )
return true;
else
return false;
}
}

produces the output:

fred is not an integer 
10 is an integer

instantiate python object within a c function called via ctypes

Thanks to Armin Rigo for the hint. The problem is that libraries loaded via ctypes.CDLL() create functions that release the GIL when calling into the native code. As far as I can tell this means that in order for the native function to call back into python code, it would need to acquire the GIL first using the python C API.

The easier alternative is to use ctypes.PyDLL(), which does not release the GIL (it also checks the python error flag). The documentation says, "Thus, this is only useful to call Python C API functions directly." My code is more indirect, in that I have python code calling into my own C functions, which then call into the python C API, but the problem is the same.

Determining if get handler in Proxy object is handling a function call

It's possible in a very hacky way. We return a function if the property is undefined. If this function is called, then we know the user was trying to call the property as a function. If it never is, it was called as a property. To check if the function was called, we take advantage of the fact that a Promise's callback is called in the next iteration of the event loop. This means that we won't know if it's a property or not until later, as the user needs a chance to call the function first (as our code is a getter).

One drawback of this method is that the value returned from the object will be the new function, not undefined, if the user was expecting a property. Also this won't work for you if you need the result right away and can't wait until the next event loop iteration.

const obj = {

func: undefined,

realFunc: () => "Real Func Called",

prop: undefined,

realProp: true

};

const handlers = {

get: (target, name) => {

const prop = target[name];

if (prop != null) { return prop; }

let isProp = true;

Promise.resolve().then(() => {

if (isProp) {

console.log(`Undefined ${name} is Prop`)

} else {

console.log(`Undefined ${name} is Func`);

}

});

return new Proxy(()=>{}, {

get: handlers.get,

apply: () => {

isProp = false;

return new Proxy(()=>{}, handlers);

}

});

}

};

const proxied = new Proxy(obj, handlers);

let res = proxied.func();

res = proxied.func;

res = proxied.prop;

res = proxied.realFunc();

console.log(`realFunc: ${res}`);

res = proxied.realProp;

console.log(`realProp: ${res}`);

proxied.propC1.funcC2().propC3.funcC4().funcC5();

Accept any kind of callable and also know argument type

Here's an example that will work for most callables including functors and lambdas (although not for generic functors as @Yakk demonstrated in a comment on the question).

The code can also be useful when determining return type and multiple arguments.

template <typename T>
struct func_traits : public func_traits<decltype(&T::operator())> {};

template <typename C, typename Ret, typename... Args>
struct func_traits<Ret(C::*)(Args...) const> {
using result_type = Ret;

template <std::size_t i>
struct arg {
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
};

template <typename T>
void option(T&& t) {
using traits = func_traits<typename std::decay<T>::type>;

using return_t = typename traits::result_type; // Return type.
using arg0_t = typename traits::template arg<0>::type; // First arg type.

// Output types.
std::cout << "Return type: " << typeid(return_t).name() << std::endl;
std::cout << "Argument type: " << typeid(arg0_t).name() << std::endl;
}

To add support for regular functions add a specialization e.g.

template <typename Ret, typename... Args>
struct func_traits<Ret(*)(Args...)> { /* ... */ }

More useful info: Is it possible to figure out the parameter type and return type of a lambda?

Why PyCallable_Check() returns 0 on global class instances?

That's not a callable. You may be misunderstanding what "callable" means.

If globalObj were callable, you would be able to do globalObj(), perhaps with some appropriate arguments between the parentheses. You can't.

Unable to fix a 'float' object is not callable error

You are iterating over your sequence and are calling the item data; this got you confused that data is the sequence.

You are also missing an operator between two expressions in parenthesis: distance = ((6371 * math.pi) / 180) MISSING OPERATOR HERE (math.sqrt((-35.276159 - latitude) ** 2 + (149.120893 - longitude) ** 2)) - this corresponds to (float)(float) after partial evaluation, which is attempting to call a float.

for item in seq:
latitude = float(item)
longitude = float(item)
distance = ((6371 * math.pi) / 180)**2 + (math.sqrt((-35.276159 - latitude) ** 2 + (149.120893 - longitude) ** 2))
print(distance)

Note:

Please do not use python keywords (list) to name variables.

How to determine if a type implements an interface with C# reflection

You have a few choices:

  1. typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
  2. typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
  3. With C# 6 you can use typeof(MyType).GetInterface(nameof(IMyInterface)) != null

For a generic interface, it’s a bit different.

typeof(MyType).GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))


Related Topics



Leave a reply



Submit