python对象是单例函数吗?

shi*_*eta 4 python

在Java中,对象使用链接到它们的类的函数的完整副本进行实例化.这是Spring Framework如此成功的原因之一.Spring可以帮助您减少Java VM在创建许多临时数据对象时使用的内存,以及Spring提供的其他服务对象作为有效承载所有功能的单例.

我只是想知道在Python中这是真的吗?好像不是.但这意味着如果你弄乱了一个对象的dict,那么你正在改变该类的所有副本的所有功能,对吗?

例如:

class MyObj:
  a = 23

  def __init__(self, b):
     self.b = b

  def __add__(self, c):
     return self.b + c
Run Code Online (Sandbox Code Playgroud)

如果我创建一个数组MyObj,是否有一个实例,__add__每个实例,或只有一个实例?

ste*_*eha 6

该函数只有一个实例,它存储在类中.该函数通过引用类实例作为第一个参数进行调用,该参数通常被称为self.

所以,这里有三种等效方法来调用.__add__()方法函数:

>>> x = MyObj(2)
>>> MyObj.__add__(x, 3)  # we pass in a reference to x explicitly
5
>>> x.__add__(3)  # method call implicitly passes reference to x
5
>>> x + 3  # overloaded operator implicitly passes reference to x
5
Run Code Online (Sandbox Code Playgroud)

此外,在Python中,函数的"类型签名"不是函数名称的一部分..__add__()您获得的唯一方法是您声明的方法.在Python中,您只需编写代码,使一个函数执行您可能希望它执行的所有不同作业.例如,如果.__add__()要将字符串转换为整数以x + "3"返回5,则可以这样做:

class MyObj(object): # see note 0
    a = 23
    def __init__(self, b):
        self.b = b
    def __add__(self, other):
        return self.b + int(other)  # see note 1
    def a_add(self, other):
        return MyObj.a + other
Run Code Online (Sandbox Code Playgroud)

注0:最好将您的类声明为继承object.在Python 3.x中,你的类将继承object你是否以这种方式声明它,但是在Python 2.x中你会得到一个"旧式类",除非你(object)在类名之后声明它.

注1:我们不打算检查other参数的类型; 我们只是试图强迫它达到int价值.这是"鸭子打字"的行动.现在不仅将字符串强制转换为整数,而且任何可以成功强制转换为字符串的东西都可以int工作.

有时,要使一个函数执行多个作业,您可能需要额外的参数.您可以将它们设置为可选,这样您每次调用该函数时都不需要指定它们.您可以在Python教程中阅读更多相关内容; 这里有一个地方:http://diveintopython.net/power_of_introspection/optional_arguments.html

最后,在Python中,您需要显式地使用MyObj.a来引用该类变量a.如果您只是a在成员函数中使用,您将获得通常的名称解析规则,它将在全局命名空间中查找; 对象命名空间并不特殊.

你也可以像这样得到一个类变量:

def a_add(self, other):
    cls = type(self)  # cls will be set to the class
    return cls.a + other
Run Code Online (Sandbox Code Playgroud)

但是只有当它是一个继承自的新式类时才会起作用object!