我有一个具有许多默认值的类,因为我无法重载函数。有没有比使用多个默认参数或使用 kwargs 更好的方法?
我考虑过将字典传递给我的类,但是如何控制是否传递必要的参数?
是否有一种更Pythonic的方式来允许参数而不将它们全部定义为默认值?
例如,我允许许多默认值:
class Editor:
def __init__(self,
ffmpeg: str,
font_file=None,
font_size=148,
font_color="white",
title_length=5,
title_x="(w-text_w)/2",
title_y="(h-text_h)/2",
box=1,
box_color="black",
box_opacity=0.5,
box_border_width=25):
self.ffmpeg = ffmpeg
self.title s= define_title(
font_file, font_size, font_color, title_length)
self.box = define_box(
box, box_color, box_opacity, box_border_width},
self.coordinates = {"x": title_x, "y": title_y}
Run Code Online (Sandbox Code Playgroud)
在其他语言中,我可能会重载构造函数。
在正常情况下,通过省略这些参数来调用具有默认参数的函数。但是,如果我正在即时生成参数,省略一个并不总是那么容易或优雅。有没有办法显式使用函数的默认参数?也就是说,传递一个指向默认参数的参数。
所以像这样的东西除了~use default~被一些智能的东西所取代。
def function(arg='default'):
print(arg)
arg_list= ['not_default', ~use default~ ]
for arg in arg_list:
function(arg=arg)
# output:
# not_default
# default
Run Code Online (Sandbox Code Playgroud)
我不知道这是否可能,并且考虑到术语“默认参数”,我所有的搜索都是编码人员的第一个教程。如果不支持此功能也没关系,我只想知道。
我将从 Python 转向 Javascript。在 Python 中,如果使用列表或字典作为函数的默认参数,则每次调用都会看到相同的对象。所以如果你有一个像这样的函数:
def append_to_list(lst=[]):
lst.append(1)
return lst
Run Code Online (Sandbox Code Playgroud)
然后这样称呼它:
lst1 = append_to_list()
lst2 = append_to_list()
Run Code Online (Sandbox Code Playgroud)
lst2将会有价值[1, 1]而不仅仅是[1]
Javascript 对于默认参数也有同样的问题吗?
我试图捕获thislambda 函数中的指针,该函数用作方法的默认参数。
我的目标是从 lambda 中调用此类的方法,这需要捕获指针this。
但是,以下代码会导致错误:
错误 C3639:作为默认参数一部分的 lambda 只能有一个 init-capture
克服此限制的常见解决方案是什么?
#include <functional>
class A{
public:
void B(std::function<void()> a = [this](){}); //error C3639: a lambda that is part of a default argument can only have an init-capture.
};
Run Code Online (Sandbox Code Playgroud) 假设我有一个函数将函数指针作为参数,该参数有一个默认参数.
template <typename T>
T* default_construct()
{
return new T();
}
template <typename T>
void register(T* (*construct)() = default_construct<T>)
{
// Save that function pointer for later
}
Run Code Online (Sandbox Code Playgroud)
假设我想在我的类上使用register Foo,但是Foo没有默认的构造函数,所以我default_construct不会对它起作用.显而易见的解决方案是做这样的事情:
Foo* construct_Foo()
{
return new Foo("String argument", 123);
}
SomeFunc()
{
// ...
register<Foo>(construct_Foo);
// ...
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用.即使register<Foo>可能只在一个地方调用,并且它传递了一个要使用的函数,default_construct<Foo>仍然会被编译器实例化,并且我得到编译器错误.似乎因为它永远不会被使用,它应该被跳过,但我想情况并非如此.
default_construct当它被用作默认参数时,有什么方法可以防止被实例化?我能想到的唯一解决方案是将它放在模板中,但似乎应该有更好的解决方案.
我正在尝试创建一个类,用户可以在其中修改成员变量以更改其成员函数的默认参数.
class Class
{
public int Member;
public void Method(int Argument = Member)
{
// This compiles fine, until I try to actually use
// the method elsewhere in code!
// "Error: need 'this' to access member Member"
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的解决方法是使用幻数,这显然不太理想.
public void Method(int Argument = 123)
{
int RealArgument;
if (Argument == 123) RealArgument = Member;
else RealArgument = Argument;
}
Run Code Online (Sandbox Code Playgroud)
有更好的方法,还是我坚持使用这种"黑客"解决方案?
parameters d member-functions member-variables default-arguments
这个链接没有回答我的问题所以我会在这里问:
基本上我想写一个模板函数
template <typename Out, typename In>
Out f(In x);
Run Code Online (Sandbox Code Playgroud)
在这里,我总是需要Out在调用时指定f.我不想每次都这样做,所以我基本上都想要
template <typename Out = In, typename In>
Out f(In x);
Run Code Online (Sandbox Code Playgroud)
这意味着如果我没有指定Out,它将默认为In.但是,这在C++ 11中是不可能的.
所以我的问题是,有没有办法达到这个效果:
f(t)将实例化f<T,T>(t)或更普遍f<typename SomeThing<T>::type, T>f<U>(t)将实例化f<U, T>(t)如果我们对静态成员变量使用默认参数,是否有任何陷阱?像这样:
enum Index
{
INDEX_A = 0,
INDEX_B
};
class foo
{
public:
static void method1( int a, int b = INDEX_A);
};
Run Code Online (Sandbox Code Playgroud)
编译器永远不会抱怨,但是当它与静态有关时我总是很谨慎.
我用3个参数声明了一个C++函数声明,其中两个默认值是这样的.
void func(int const n, bool const flag=true, int *array=NULL) {
/* print contents of array */
}
Run Code Online (Sandbox Code Playgroud)
当我错误地调用函数时,省略第二个参数但包括第三个参数,就像这样
int array[5]={1,2,3,4,5};
func(5,array);
Run Code Online (Sandbox Code Playgroud)
gcc和intel编译器(Ubuntu 14.04 LTS上的默认编译器)都没有抱怨指定了最后一个参数而没有指定倒数第二个参数.代码运行但是为数组发送了NULL(我希望代码失败).
我的问题是为什么编译器没有抱怨它找不到匹配的函数,因为我的调用的签名应该出现为
funct(int const, int *)
Run Code Online (Sandbox Code Playgroud)
我可以在编译期间打开哪些选项来触发有关此错误使用的警告?
我是运算符重载试验new和delete,并注意到MSVC和GCC出现在他们的实施而不同operator delete.请考虑以下代码:
#include <cstddef>
struct CL {
// The bool does nothing, other than making these placement overloads.
void* operator new(size_t s, bool b = true);
void operator delete(void* o, bool b = true);
};
// Functions are simple wrappers for the normal operators.
void* CL::operator new(size_t s, bool b) { return ::operator new(s); }
void CL::operator delete(void* o, bool b) { return ::operator delete(o); }
auto aut = new (false) CL;
Run Code Online (Sandbox Code Playgroud)
此代码将使用GCC(使用Ideone和TutorialsPoint在线编译器进行测试)进行正确编译,但不能使用MSVC(使用MSVS 2010,MSVS …
c++ ×6
python ×3
templates ×2
c++11 ×1
class ×1
constructor ×1
d ×1
g++ ×1
javascript ×1
lambda ×1
parameters ×1
static ×1
this ×1
visual-c++ ×1