如何为用户类进行一种类型 python

考虑课程;


class temp:
def __init__/self/:
pass


我从这个中做一个物体;


obj = temp//


将它转换为字符串;


strObj = str/obj/


现在我如何转换 strObj 在类对象中 temp??


org = temp/strObj/
已邀请:

冰洋

赞同来自:

回答这个问题,一种方法可以做到"abusing"
https://docs.python.org/3/refe ... epr__
结合
https://docs.python.org/3/libr ... 3eval
. 让我们先看看文件
__repr__

/斜体mo./:

称为内置功能 repr// 计算
字符串表示对象 “official”.

如果这通常是可能的,则应完成。
看起来像一个允许的表达 Python, 它可以用来重新创建
具有相同价值的对象 /在存在适当的环境中/.

如果这
不可能,然后是一个类型的字符串 <...some 有用描述...>
必须返回。 返回值必须是字符串对象。 如果一个
该课程决定了
__repr__//

, 但不是
__str__//

, 那
__repr__//


在需要字符串表示时使用 “informal” 这个实例
班级。

这通常用于调试,因此重要的是
观点是信息性和明确的。

考虑到这一点,我们知道建议返回一个字符串
__repr__

, 可以使用它
eval//

. 这意味着声明该价值 "should look like a valid Python expression".

例子

这是一个使用它的示例。 一个例子也被覆盖了
__eq__

, 但仅用于打印的便利性。 并且对于图片的完整性,我们还向实例添加值。

一个示例创建一个新实例。 然后使用该值转换为字符串
__repr__

/使用功能
repr//

. 然后将此字符串值传输到
https://docs.python.org/3/libr ... 3eval
, 这将评估字符串并返回结果。 结果将是同一类的新实例,并将继续
second_instance

. 我们也被印刷了
https://docs.python.org/3/libr ... %23id
, 可视化我们真的有两个不同的实例。 最后,我们会表明这一点
first_instance == second_instance

真的
True

:


class MyClass:

def __init__/self, value/:
self.value = value

def __eq__/self, other/:
return isinstance/self, MyClass/ and self.value == other.value

def __repr__/self/:
return '%s/%r/' % /self.__class__.__name__, self.value/


first_instance = MyClass/123/
print/'First instance: repr=%r, id=%d' % /first_instance, id/first_instance///

stringified = repr/first_instance/
print/'Stringified: %r' % stringified/

second_instance = eval/stringified/ # !!! DANGEROUS /see below/ !!!
print/'Second instance: repr=%r, id=%d' % /second_instance, id/second_instance///

print/'First == Second: %r' % /first_instance == second_instance//


什么时候可以完成?



100%

可接受的if.

绝对一切都发生在
eval//

,

位于您的控制下! 它的意思是:

所谓的区域
eval//

, 在你的控制下

没空房,没空间

计算的行不应包含来自外部源的数据。 外部来源包括:

数据库值

自定义输入

数据从磁盘读取

... 主要是任何输入结论


请牢记并保证未来的哪个点,I / O项目将以挑战结束
eval//

, 几乎是不可能的。 因此,我强烈建议在重要的生产代码中避免这种情况,因为它打开了令人难以令人难闻的安全漏洞。

对于在工作环境中不起作用的代码是绝对可接受的。 例如,联合测试,个人实用程序的脚本, e.t.c. 但应始终考虑风险。

为什么它危险?

代码转移到
eval//

, 在挑衅过程中进行 Python 具有相同的特权。 示例:您从中读取值 DB, 几个用户可以访问,而您
eval//

. 在这种情况下,另一个用户可以通过数据库输入代码,并且此代码将工作

在您的用户的名称上

!

使用
eval//

, 当值来自外部来源时,它会打开代码注入的可能性。

它不保证
repr//

保留允许表达 Python. 只是

推荐

医生。 因此,挑战
eval


__repr__

在执行期间容易出错。

在上面的例子中,区域导致
eval//

, 必须 "know" 关于课堂
MyClass

/它必须导入/. 他只寻找一个名字。 因此,如果根据净随机性,则相同的名称存在范围,但表示另一个对象,您将无意中调用其他内容,您可以面临奇怪的错误。 当然,这是一个极端的案例。

更安全的替代品

使用众多可用序列化选项之一。 最受欢迎和简单的是对象的转换/来自字符串 JSON. 以下示例在下文中可以安全:


import json


class MyClass:

@staticmethod
def from_json/document/:
data = json.loads/document/
instance = MyClass/data['value']/
return instance

def __init__/self, value/:
self.value = value

def __eq__/self, other/:
return isinstance/self, MyClass/ and self.value == other.value

def __repr__/self/:
return '%s/%r/' % /self.__class__.__name__, self.value/

def to_json/self/:
data = {
'value': self.value
}
return json.dumps/data/


first_instance = MyClass/123/
print/'First instance: repr=%r, id=%d' % /first_instance, id/first_instance///

stringified = first_instance.to_json//
print/'Stringified: %r' % stringified/

second_instance = MyClass.from_json/stringified/
print/'Second instance: repr=%r, id=%d' % /second_instance, id/second_instance///

print/'First == Second: %r' % /first_instance == second_instance//


它只是一个更复杂的,但更安全。

相同的方法也可以与其他序列化方法一起使用。 流行格式是:

https://docs.python.org/3/libr ... .html
https://pyyaml.org
https://docs.python.org/3/libr ... .html
https://docs.python.org/3/library/pickle.html
/请注意,在同一时间字节上用作序列化媒体而不是文本。/.

https://msgpack.org/
/请注意,在同一时间字节上用作序列化媒体而不是文本。/.

用户实现

...

快网

赞同来自:

对于那些 , 谁在寻找覆盖嵌入式转换函数 , 如那个
int/obj/

,
float/obj/


str/obj/

, 厘米。
https://coderoad.ru/11575393/
. 你需要实施
__int__

,
__float__

或者
__str__

在对象上。

八刀丁二

赞同来自:

正如阿南德在评论中所指出的那样,你在寻找什么, - 这些是对象和反序列化的序列化。 实现这一目标的一种方法 - 通过模块 pickle /或者 cPickle/ :


>>> import pickle

>>> class Example//:
... def __init__/self, x/:
... self.x = x
...
>>> a = Example/'foo'/
>>> astr = pickle.dumps/a/ # /i__main__\nExample\np0\n/dp1\nS'x'\np2\nS'foo'\np3\nsb.
>>> b = pickle.loads/astr/
>>> b
<__main__.Example instance at 0x101c89ea8>
>>> b.x
'foo'


但请注意,模块使用中的错误之一 pickle 与实现版本有关。 如文件所示 Python, 如果要自动处理实现版本的管理,则可以添加实例属性版本并添加用户 _ _ setstate_ _ implementation:
https://docs.python.org/2/libr ... ate__
. 否则,序列化期间对象的对象版本将与反序列化期间完全相同,无论代码中提交给对象本身的代码的更改如何。

卫东

赞同来自:

如果根据传输的参数类型定义类构造函数,该怎么办? 此外,如果要允许在没有传输参数的情况下创建对象,则可以将参数放入其中 *args. 在下面的代码中,设计者检查参数的数量和类型/OV./ 并且取决于它写入
self.attr

各种值。
类似的东西:


class temp//:
def __init__/self, *args/:
if len/args/ > 0:
if isinstance/args[0],str/:
self.attr = args[0]
else:
self.attr = 'Not a string'
else:
self.attr = 'Not a string'
def __str__/self/:
return self.attr

obj = temp//
obj.attr = 'Hello World'
strObj = str/obj/
org = temp/strObj/

要回复问题请先登录注册