Define a Method Outside of Class Definition

Define a method outside of class definition?

Yes. You can define a function outside of a class and then use it in the class body as a method:

def func(self):
print("func")

class MyClass:
myMethod = func

You can also add a function to a class after it has been defined:

class MyClass:
pass

def func(self):
print("func")

MyClass.myMethod = func

You can define the function and the class in different modules if you want, but I'd advise against defining the class in one module then importing it in another and adding methods to it dynamically (as in my second example), because then you'd have surprisingly different behaviour from the class depending on whether or not another module has been imported.

I would point out that while this is possible in Python, it's a bit unusual. You mention in a comment that "users are allowed to add more" methods. That sounds odd. If you're writing a library you probably don't want users of the library to add methods dynamically to classes in the library. It's more normal for users of a library to create their own subclass that inherits from your class than to change yours directly.

I'd also add a reminder that functions don't have to be in classes at all. Python isn't like Java or C# and you can just have functions that aren't part of any class. If you want to group together functions you can just put them together in the same module, and you can nest modules inside packages. Only use classes when you need to create a new data type, not just to group functions together.

Define a staticmethod outside of class definition?

Decorator syntax is only used for function and class definitions, but is only necessary in those cases to avoid repetition of names. The syntax is just a shortcut for assignments, so you can write

def some_heavy_method(...):
...

class some_class:
some_heavy_method = staticmethod(some_heavy_method

The decorator syntax is always just a convenience; without it, you could always simply write

class some_class:

def f():
...

f = staticmethod(f)

defining class methods outside of the class Python

The two versions are completely equivalent (except that the first version also introduces my_func into the global namespace, of course, and the different name you used for the first parameter).

Note that there are no "class methods" in your code – both definitions result in regular (instance) methods.

A function definition results in the same function object regardless of whether it occurs at class or module level. Therefore, the assignment in the first version of the code lifts the function object into the class scope, and results in a completely equivalent class scope as the second version.

How to define a specialized class method outside of class body in C++?

I'm pretty sure that both the MS and Clang compilers are in error here and GCC is compiling your code correctly. Until these bugs are fixed in the other compilers, I suggest to continue using the concept pattern instead of going back to outdated methods. Simply work around the bug using an additional class:

#include <concepts>
#include <iostream>

// This is a work-around for using concept specialization of
// classes in conjunction with out-of-body definition of members.
// Only helpful for MSVC and Clang. GCC is properly compiling
// out-of-body concept specializations.

template <typename T>
class A
{
// For MSVC ONLY: the default template seems require being empty
// for this to work, but do fiddle around with it.

// (Also works with MSVC:)
A() = delete;
A(const A&) = delete;
A(A&&) noexcept = delete;
A& operator =(const A&) = delete;
A& operator =(A&&) noexcept = delete;
~A() = delete;

// Clang and GCC can have members just fine:
// static const char* foo();
};

// We use distinct base classes to define our concept specializations of A.
template <std::signed_integral T>
class A_Signed_Integral
{
public:
static const char* foo();
};
template <std::unsigned_integral T>
class A_Unsigned_Integral
{
public:
static const char* foo();
};

// And then we wrap them using the actual concept specializations of A,
// making the specializations effectivel the same class as the base class.
template <std::signed_integral T>
class A<T> :
public A_Signed_Integral<T>
{
public:
using A_Signed_Integral<T>::A_Signed_Integral; // grab all ctors
using A_Signed_Integral<T>::operator =; // an exceptional case
};
template <std::unsigned_integral T>
class A<T> :
public A_Unsigned_Integral<T>
{
public:
using A_Unsigned_Integral<T>::A_Unsigned_Integral;
using A_Unsigned_Integral<T>::operator =;
};

// Out-of-body definitions can be located to another file
template <std::signed_integral T>
inline const char* A_Signed_Integral<T>::foo()
{
return "using A<std::signed_integral T> foo";
}

template <std::unsigned_integral T>
inline const char* A_Unsigned_Integral<T>::foo()
{
return "using A<std::unsigned_integral T> foo";
}

int main()
{
std::cout << A<signed long>::foo() << std::endl;
std::cout << A<unsigned long>::foo() << std::endl;

return 0;
}

(Tested with all three compilers and works fine: see gcc.godbolt.org)

In the future, once the bugs are fixed it should be relatively easy with search and replace to erase the base classes in favor of just using the concept specializations of A.

EDIT:
Updating the example to work for MSVC, which cannot seem to make use of the default template yet.

Code completion for defining a method outside of class definition?

Thanks to @Anentropic I was able to answer my own question (screenshot with autocompletion):

from dataclasses import dataclass

class GetMixin:
def get_dap(self):
pass

@dataclass
class Country:
ctr_cc: str
ctr_code: str
ctr_name: str

@dataclass
class Region(GetMixin, Country):
reg_code: str
reg_name: str

if __name__ == '__main__':
dk1 = Region(ctr_cc="DK",
ctr_code="DENMARK",
ctr_name="Denmark",
reg_code="DK1",
reg_name="East Denmark")
dk1.get_dap()

Using a mixin and inheriting it in your preferred classes provides a better method for reuse and allows for autocompletion.

Can you define a static method outside of a class?

A static method without a class does not make any sense at all. The static keywords signals that this method is identical for all instances of the class. This enables you to call it.. well.. statically on the class itself instead of on one of its instances.

If the content of the method is self-contained, meaning it does not need any other static variables or methods of the class, you can simply omit the class and put the code in a global method. Using global methods is considered a bad practice.

So my advice is to just keep the class, even if it has only that one method within. This way you can still autoload the file instead of having to require it yourself.



Related Topics



Leave a reply



Submit