如何根据参数类型重载 __init__ 方法?
假设我有一个类,它有一个名为 data 的成员,它是一个列表。
我希望能够使用文件名(其中包含用于初始化列表的数据)或实际列表来初始化类。
你这样做的技术是什么?
你只是通过查看__class__
来检查类型吗?
我可能缺少一些技巧吗?
我习惯了 C++,其中按参数类型重载很容易。
Let's say I have a class that has a member called data which is a list.
I want to be able to initialize the class with, for example, a filename (which contains data to initialize the list) or with an actual list.
What's your technique for doing this?
Do you just check the type by looking at __class__
?
Is there some trick I might be missing?
I'm used to C++ where overloading by argument type is easy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
你为什么不变得更加Pythonic呢?
Why don't you go even more pythonic?
太好了。 我只是将这个示例与元组(而不是文件名)放在一起,但这很简单。 谢谢大家。
a = [1,2]
b = (2,3)
c = MyData(a)
d = MyData(b)
c.GetData()
d.GetData()
[1, 2]
[2, 3]
OK, great. I just tossed together this example with a tuple, not a filename, but that's easy. Thanks all.
a = [1,2]
b = (2,3)
c = MyData(a)
d = MyData(b)
c.GetData()
d.GetData()
[1, 2]
[2, 3]
我的首选解决方案是:
然后使用
MyClass()
或MyClass([1,2,3])
调用它。希望有帮助。 快乐编码!
My preferred solution is:
Then invoke it with either
MyClass()
orMyClass([1,2,3])
.Hope that helps. Happy Coding!
你应该使用 isinstance
You should use isinstance
您可能需要
isinstance
内置函数:You probably want the
isinstance
builtin function:快速而肮脏的修复
然后你可以调用它
Quick and dirty fix
Then you can call it with
更好的方法是使用 isinstance 和类型转换。 如果我理解正确的话,你想要这个:
A better way would be to use isinstance and type conversion. If I'm understanding you right, you want this:
很好的问题。 我也解决了这个问题,虽然我同意“工厂”(类方法构造函数)是一个很好的方法,但我想建议另一种方法,我也发现它非常有用:
这是一个示例(这是一个
read
方法而不是构造函数,但想法是相同的):这里的关键想法是使用 Python 对命名参数的出色支持来实现这一点。 现在,如果我想从文件中读取数据,我会说:
要从字符串中读取数据,我会说:
这样用户只需调用一个方法。 正如您所看到的,在内部处理它并不太复杂
Excellent question. I've tackled this problem as well, and while I agree that "factories" (class-method constructors) are a good method, I would like to suggest another, which I've also found very useful:
Here's a sample (this is a
read
method and not a constructor, but the idea is the same):The key idea is here is using Python's excellent support for named arguments to implement this. Now, if I want to read the data from a file, I say:
And to read it from a string, I say:
This way the user has just a single method to call. Handling it inside, as you saw, is not overly complex
获得“备用构造函数”的一种更简洁的方法是使用类方法。 例如:
它更整洁的原因是毫无疑问需要什么类型,并且您不必猜测调用者打算让您如何处理它给您的数据类型。 isinstance(x, basestring) 的问题是,调用者无法告诉您,例如,即使类型不是基本字符串,您也应该将其视为字符串(而不是另一个序列。)也许调用者希望将相同的类型用于不同的目的,有时作为单个项目,有时作为项目序列。 明确可以消除所有疑问,并带来更健壮、更清晰的代码。
A much neater way to get 'alternate constructors' is to use classmethods. For instance:
The reason it's neater is that there is no doubt about what type is expected, and you aren't forced to guess at what the caller intended for you to do with the datatype it gave you. The problem with
isinstance(x, basestring)
is that there is no way for the caller to tell you, for instance, that even though the type is not a basestring, you should treat it as a string (and not another sequence.) And perhaps the caller would like to use the same type for different purposes, sometimes as a single item, and sometimes as a sequence of items. Being explicit takes all doubt away and leads to more robust and clearer code.使用 python3,您可以使用 使用函数实现多重调度正如 Python Cookbook 所写的,注释:
它的工作原理如下:
with python3, you can use Implementing Multiple Dispatch with Function Annotations as Python Cookbook wrote:
and it works like: