从字符串创建 Python 对象
一些 Python 类(例如 float
)可以解析字符串来创建对象:
number_string = "4.5"
assert float(number_string) == 4.5
这在技术上是什么?使用字符串调用构造函数?但是,如果构造函数还采用其他参数来进行通常的对象构造(而不是来自字符串)怎么办?
如何实现一个可以解析字符串来创建实例的类?
补充:
看起来float(str)
正在调用传递字符串的__float__
特殊方法 - 字符串知道它的float< /代码> 值。
每个实现 __float__
的对象都可以传递给 float(obj)
:
>>> class MyClass:
... def __float__(self):
... return 0.01
...
>>> m = MyClass()
>>> float(m)
0.01
此方法仅适用于转换为特定类型,例如 float
和 int
,因为转换实际上发生在传递的对象中。我想要的是相反的情况,转换发生在传递字符串的对象中。我认为 Paul McGuire 建议的静态 parse
方法可能是一个很好的解决方法。
Some Python classes like float
can parse strings to create objects:
number_string = "4.5"
assert float(number_string) == 4.5
What is that technically? A constructor call with a string? But what if the constructor would also take other parameters for usual object construction (not from strings)?
How to implement a class that can parse strings to create instances?
Addition:
It looks like float(str)
is calling the __float__
special method of the passed string - the string knows its float
value.
Every object implementing __float__
can be passed to float(obj)
:
>>> class MyClass:
... def __float__(self):
... return 0.01
...
>>> m = MyClass()
>>> float(m)
0.01
This approach works only with conversions to specific types like float
and int
, since the conversion actually happens in the passed object. What I want is the opposite where the conversion happens in the object which gets the string passed. I think a static parse
method, as suggested by Paul McGuire, could be a good work around.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个带有字符串的构造函数调用。如果您的构造函数需要的不仅仅是字符串值,那么您可以定义一个类方法工厂方法,该方法接受一个字符串,从中提取附加数据(无论您如何对其进行编码),然后使用所有必要的参数调用构造函数。 @tiagoboldt 引用了此类定义:
我将添加此方法来接受“姓名/年龄/性别”形式的字符串:
It is a constructor call with a string. If you have a constructor that needs more than the string value, then you could define a classmethod factory method that takes a string, extracts the additional data from it (however you have encoded it), and then calls the constructor with all the necessary args. @tiagoboldt referenced this class definition:
I would add this method to accept a string of the form "name/age/gender":
这只是根据参数类型以不同方式处理参数的一般情况。通常,除非绝对必要,否则测试类型被认为是不好的形式,但 Python 拥有
type()
和isinstance()
是有原因的!您会注意到,
dict()
构造函数可以采用现有的字典对象、键/值对元组的列表(或其他可迭代对象)或关键字参数(作为字典到达构造函数) ,但作为与选项 1) 不同的参数。在 Java 或其他静态类型语言中,这些都是不同的构造函数方法。但在 Python 中,任何类型都可以在任何参数中传递。只有一个构造函数(或初始值设定项)。因此,
dict
类型必须在其__init__()
方法中具有一些智能,以将字典或列表作为第一个参数以及可选的关键字参数进行处理。两者都必须是可选的。它的实现方式看起来像这样:(使用自己类型的对象定义一个类是有问题的,所以我确信我写的内容实际上不会运行,而且除了 dict 之外,实际上是用 C 实现的,但希望您能明白这个想法。)
在您自己的对象中,您可以将某些参数设置为可选,并根据需要测试参数的类型,以便根据传入的内容以不同的方式处理它们。如果您想如果能够处理字符串,您可以在 Python 2.x 中使用
isinstance(arg, basestring)
(以便测试同时匹配常规字符串和 Unicode 字符串)或仅使用isinstance(arg, str)
Python 3 中的 code>。Paul 建议的工厂类方法也不是一个坏主意,特别是对于可以通过多种方式执行初始化的类。我会将此类方法命名为
from_str()
等。This is just a general case of handling arguments differently based on their types. Usually it is considered bad form to test types unless it's absolutely necessary, but Python has
type()
andisinstance()
for a reason!You will notice that the
dict()
constructor can take an existing dictionary object, a list (or other iterable) of tuples of key/value pairs, or keyword arguments (which arrive at the constructor as a dictionary, but as a different argument from option 1). In Java or another statically-typed language, these would all be different constructor methods. But in Python, any type can be passed in any argument. There is only one constructor (or initializer).So the
dict
type has to have some smarts in its__init__()
method to handle either a dict or a list as the first argument, and also an optional keyword argument. Both must be optional. The way it's implemented would look something like this:(Defining a class using objects of its own type is problematic, so I'm sure what I've written wouldn't actually run, and besides
dict
is actually implemented in C, but you hopefully get the idea.)In your own objects, then, you can make certain arguments optional, and test the types of arguments as necessary to handle them differently depending on what's passed in. If you want to be able to handle strings, you can use
isinstance(arg, basestring)
in Python 2.x (so the test matches both regular and Unicode strings) or justisinstance(arg, str)
in Python 3.Factory class methods as suggested by Paul are not a bad idea either, especially for classes where initialization can be performed in a large number of ways. I would name such methods
from_str()
or so on.并在使用中:
and in usage:
你正在做的就是演员阵容。从字符串实现构造函数的最佳方法是使用 init 方法并将字符串传递给它。
一个更复杂的示例(不仅仅是一个字符串): http://www.java2s .com/Code/Python/Class/Averysimpleclasswithaconstructor.htm
What you're doing is a cast. The best way to implement a constructor from a string is to use the init method and pass the string to it.
A more complex example (more than just one string): http://www.java2s.com/Code/Python/Class/Averysimpleclasswithaconstructor.htm