如何为python自定义类进行类型转换

如何为python自定义类进行类型转换,python,class,python-2.7,casting,Python,Class,Python 2.7,Casting,考虑一个类 class temp: def __init__(self): pass 我把它当作目标 obj = temp() 将其转换为字符串 strObj = str(obj) 现在,如何将strObj转换为temp类的对象 org = temp(strObj) 正如Anand在评论中所指出的,您需要的是对象序列化和反序列化。实现这一点的一种方法是通过pickle(或cPickle)模块: 导入pickle >>>类示例(): ... 定义初始化(se

考虑一个类

class temp:
    def __init__(self):
        pass
我把它当作目标

obj = temp()
将其转换为字符串

strObj = str(obj)
现在,如何将strObj转换为temp类的对象

org = temp(strObj)

正如Anand在评论中所指出的,您需要的是对象序列化和反序列化。实现这一点的一种方法是通过pickle(或cPickle)模块:

导入pickle >>>类示例(): ... 定义初始化(self,x): ... self.x=x ... >>>a=示例('foo') >>>astr=pickle.dumps(a)#(i_uuumain_uu\n例如\np0\n(dp1\nS'x'\np2\nS'foo'\np3\nsb)。 >>>b=酸洗负荷(应力应变率) >>>b >>>b.x “福”
但是,请注意,使用pickle模块时遇到的一个问题是处理实现版本。正如Python文档中所建议的,如果您希望一个未经pickle的实例自动处理实现版本控制,则可能需要添加一个version实例属性并添加一个自定义的_usetstate__;实现:。否则,ob的版本无论对对象本身所做的代码更改如何,序列化时的对象将与反序列化时的对象完全相同。

对于那些希望覆盖转换内置项的人,例如
int(obj)
float(obj)
,和
str(obj)
,请参见。您需要在对象上实现
\uuuu int\uuuuuuu
\uuuu float\uuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu str

要回答这个问题,一种方法是结合使用“滥用”。让我们首先看看
\uuu repr\uuuucode>文档(重点:我的):

由repr()内置函数调用以计算“官方” 对象的字符串表示形式。如果可能,应该 看起来像一个有效的Python表达式,可以用来重新创建 对象具有相同的值(给定适当的环境)。如果 是不可能的,一个字符串的形式 应返回。返回值必须是字符串对象。如果 类定义了
\uuuuu repr\uuuuu()
但不定义
\uuuu str\uuuuuu()
,那么
\uuuuuu repr\uuuuuu()
也是 当该实例的“非正式”字符串表示形式时使用 课程是必修的

这通常用于调试,因此 表示是信息丰富且明确的

考虑到这一点,我们知道建议从
\uuuu repr\uuuu
返回一个字符串,该字符串可以与
eval()
一起使用。这一点可以通过以下语句得到暗示:值“应该看起来像一个有效的Python表达式”

例子 下面是一个使用此方法的示例。该示例也覆盖了
\uuuuueq\uuuuuu
,但只是为了方便打印输出。为了完整性,我们还向该实例添加了一个值

该示例创建一个新实例。然后使用
\uuuu repr\uuu
将该值转换为字符串(通过使用该函数。接下来,该字符串值将被传递给该字符串,该字符串将计算该字符串并返回结果。结果将是同一类的新实例,并存储在
second\u instance
中。我们还打印了该函数,以可视化我们确实有两个不同的实例。最后,我们显示
first\u instance==second\u instance
确实是
正确的

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))
什么时候可以这样做? 如果进入
eval()
的所有内容都在您的控制之下,则这是100%可接受的!这意味着:

  • 调用
    eval()
    的范围在您的控制之下
  • 计算字符串中的任何位置都不应包含来自外部源的数据。外部源包括:
    • 数据库值
    • 用户输入
    • 从磁盘读取的数据
    • …基本上是任何I/O
记住所有这些,并保证在项目的未来任何时候I/O都不会以
eval()
调用结束,这几乎是不可能的。因此,我强烈建议在重要的生产代码中避免这种情况,因为它会打开严重的安全漏洞

对于不在生产环境中运行的代码,这是绝对可以接受的。例如,单元测试、个人实用程序脚本、e.t.c。但应始终考虑风险

为什么这很危险?
  • 传递到
    eval()
    的代码在调用它的Python进程内以相同的权限执行。例如:您从多个用户都可以访问的数据库中读取一个值,然后
    eval()
    它。在这种情况下,另一个用户可以通过数据库注入代码,该代码将作为您的用户运行
  • 当值来自外部源时,使用
    eval()
    打开了代码注入的可能性
  • 不能保证
    repr()
    将返回有效的Python表达式。这只是文档的建议。因此,使用
    \uuu repr\uuu
    调用
    eval
    很容易出现运行时错误
  • 在上面的示例中,调用
    eval()
    的作用域需要“了解”类
    MyClass
    (必须导入)。它只查找名称。因此,如果纯粹出于偶然,作用域中存在相同的名称,但指向另一个对象,您将无意中调用其他对象,并可能会遇到奇怪的错误。当然,这是一个边缘情况
更安全的选择 使用许多可用序列化选项中的一个。最常用也是最简单的一个选项是将对象转换为JSON字符串或从JSON字符串转换为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))
这只是稍微困难一点,但要安全得多

同样的方法也可用于其他序列化方法。流行的格式有:

  • (请注意,这使用字节而不是文本作为序列化介质)
  • (请注意,这使用字节而不是文本作为序列化介质)
  • 自定义实现

如果根据传递的参数类型定义类构造函数会怎么样
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))
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)
class obj():
   def __init__(self, attribs*):
       if len(attribs)==1 and type(attribs[0])=='str':
           #your string manipulations go here
           self.content = attribs[0].upper()