__init__和self在Python中做什么?

我正在学习Python编程语言,我遇到了一些我不完全理解的东西。

在这样的方法中:

def method(self, blah):def __init__(?):........

self做了什么?它是什么意思?它是强制性的吗?

__init__方法有什么作用?为什么它是必要的?(等)

我认为它们可能是OOP结构,但我不太清楚。

1416786 次浏览

__init__确实像一个构造函数。如果您希望它们表现为非静态方法,您需要将“self”作为第一个参数传递给任何类函数。“self”是您的类的实例变量。

是的,你是对的,这些都是oop结构。

__init__是类的构造函数。self参数引用对象的实例(如C++中的this)。

class Point:def __init__(self, x, y):self._x = xself._y = y

__init__方法在分配对象的内存后被调用:

x = Point(1,2)

如果您想将值持久化到对象的方法中,在对象的方法中使用self参数很重要。例如,如果您像这样实现__init__方法:

class Point:def __init__(self, x, y):_x = x_y = y

您的xy参数将存储在堆栈上的变量中,并在init方法超出范围时被丢弃。将这些变量设置为self._xself._y将这些变量设置为Point对象的成员(在对象的生命周期内可访问)。

注意:对本答案中“构造函数”一词的使用进行一些澄清。从技术上讲,“构造函数”的职责在Python中分为两个方法。这些方法是__new__(负责分配内存)和__init__(如这里讨论的,负责初始化新创建的实例)。

在此代码中:

class A(object):def __init__(self):self.x = 'Hello'
def method_a(self, foo):print self.x + ' ' + foo

self变量代表对象本身的实例。大多数面向对象语言将此作为隐藏参数传递给对象上定义的方法;Python没有。您必须显式声明它。当您创建A类的实例并调用其方法时,它会自动传递,如…

a = A()               # We do not pass any argument to the __init__ methoda.method_a('Sailor!') # We only pass a single argument

__init__方法大致代表了Python中的构造函数。当您调用A()时,Python会为您创建一个对象,并将其作为第一个参数传递给__init__方法。任何其他参数(例如A(24, 'Hello'))也将作为参数传递-在这种情况下会导致引发异常,因为构造函数不期望它们。

简而言之:

  1. 正如它所暗示的,self引用本身-调用该方法的对象。也就是说,如果您有N个对象调用该方法,那么self.a将为N个对象中的每一个引用变量的单独实例。想象每个对象都有N个变量a的副本
  2. __init__是其他OOP语言(如C++/Java)中的构造函数。基本思想是它是一个特别方法,当创建该Class的对象时自动调用

“self”是对类实例的引用

class foo:def bar(self):print "hi"

现在我们可以创建foo的实例并调用它的方法,在这种情况下,self参数由Python添加:

f = foo()f.bar()

但是如果方法调用不在类的实例的上下文中,它也可以传入,下面的代码做同样的事情

f = foo()foo.bar(f)

有趣的是,变量名'self'只是一个约定。下面的定义将完全相同…说它是非常强大的公约,应该遵循总是,但它确实说明了语言的灵活性

class foo:def bar(s):print "hi"

请注意,self实际上可以是任何有效的python标识符。例如,我们可以很容易地从Chris B的例子中编写:

class A(object):def __init__(foo):foo.x = 'Hello'
def method_a(bar, foo):print bar.x + ' ' + foo

它的工作原理完全一样。然而,建议使用自己,因为其他pythoners会更容易识别它。

基本上,当在同一个类中的多个函数中使用变量时,您需要使用'self'关键字。至于init,它用于设置默认值,以防调用该类中的其他函数。

试试这段代码。希望它能帮助许多像我这样的C程序员学习Py。

#! /usr/bin/python2
class Person:
'''Doc - Inside Class '''
def __init__(self, name):'''Doc - __init__ Constructor'''self.n_name = name
def show(self, n1, n2):'''Doc - Inside Show'''print self.n_nameprint 'Sum = ', (n1 + n2)
def __del__(self):print 'Destructor Deleting object - ', self.n_name
p=Person('Jay')p.show(2, 3)print p.__doc__print p.__init__.__doc__print p.show.__doc__

输出:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay

一个简单的例子

希望它能有所帮助,这里有一个简单的例子,我用来理解在类中声明的变量和在__init__函数中声明的变量之间的区别:

class MyClass(object):i = 123def __init__(self):self.i = 345     
a = MyClass()print(a.i)print(MyClass.i)

输出:

345123

我自己也很难理解这一点。即使在阅读了这里的答案之后。

要正确理解__init__方法,你需要了解自我。

自参数

__init__方法接受的参数是:

def __init__(self, arg1, arg2):

但我们实际上只传递了两个参数:

instance = OurClass('arg1', 'arg2')

额外的争论从何而来?

当我们访问对象的属性时,我们通过名称(或引用)来访问它。这里的实例是对我们新对象的引用。我们使用instance.printargs.访问实例对象的printargs方法

为了从__init__方法中访问对象属性,我们需要对对象的引用。

每当调用方法时,都会将对主对象的引用作为第一个参数传递。按照惯例,您总是将第一个参数调用您的方法self。

这意味着在__init__方法中我们可以这样做:

self.arg1 = arg1self.arg2 = arg2

这里我们在对象上设置属性。您可以通过执行以下操作来验证这一点:

instance = OurClass('arg1', 'arg2')print instance.arg1arg1

像这样的值被称为对象属性。这里#0方法设置实例的art1和art2属性。

来源:http://www.voidspace.org.uk/python/articles/OOP.shtml#the-init-method

在这里,这家伙写得很好很简单:https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/

阅读上面的链接作为参考:

self?那么所有客户的self参数是什么?方法?它是什么?为什么,它的实例,当然!把另一个方式,像撤回这样的方法定义了撤回的指令从某个抽象的客户账户里取出的钱打电话来jeff.withdraw(100.0)将这些指令用于杰夫实例。

因此,当我们说def撤回(self,金额):时,我们是说,“这是如何您从客户对象(我们称之为self)中提取资金一个美元数字(我们称之为金额)。self是-取款的客户被叫来了-这不是我的意思类比也是。jeff.withdraw(100.0)只是Customer.withdraw(杰夫,100.0),这是完全有效的(如果不是经常)看到)代码。

init self可能对其他方法有意义,但是init呢?当我们调用init时,我们正在创建一个对象,那么怎么可能已经有一个self呢?Python允许我们扩展构建对象时的自我模式,即使它并不完全适合。想象一下,杰夫=客户('杰夫Knupp',1000.0)与调用jff=客户(jff,'JeffKnupp',1000.0);传入的杰夫也是结果。

这就是为什么当我们调用init时,我们通过说像self.name=name这样的东西。记住,因为self是实例,这相当于说jeff.name=name,和jeff.name='Jeff Knupp。类似地,self.balance=平衡是相同的jeff.balance=1000.0。在这两行之后,我们考虑客户对象“初始化”并准备使用。

小心你__init__

init完成后,调用者可以正确地假设对象准备好使用。也就是说,在jff=客户('Jeff Knupp',1000.0),我们可以开始对杰夫进行存款和取款调用;杰夫是一个完全初始化的对象。

在此代码中:

class Cat:def __init__(self, name):self.name = namedef info(self):print 'I am a cat and I am called', self.name

这里__init__充当类的构造函数,当一个对象被实例化时,这个函数被调用。self代表实例化对象。

c = Cat('Kitty')c.info()

上述陈述的结果将如下:

I am a cat and I am called Kitty
  1. __init__基本上是一个函数,它将"初始化"/激活类的属性用于特定对象,一旦创建并匹配到相应的类。
  2. self表示将继承这些属性的对象。
# Source: Class and Instance Variables# https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables
class MyClass(object):# class variablemy_CLS_var = 10
# sets "init'ial" state to objects/instances, use self argumentdef __init__(self):# self usage => instance variable (per object)self.my_OBJ_var = 15
# also possible, class name is used => init class variableMyClass.my_CLS_var = 20

def run_example_func():# PRINTS    10    (class variable)print MyClass.my_CLS_var
# executes __init__ for obj1 instance# NOTE: __init__ changes class variable aboveobj1 = MyClass()
# PRINTS    15    (instance variable)print obj1.my_OBJ_var
# PRINTS    20    (class variable, changed value)print MyClass.my_CLS_var

run_example_func()

自我做了什么?意味着是什么?是强制性吗?

每个类方法的第一个参数,包括init,总是对类的当前实例的引用。按照惯例,这个参数总是被命名为self。在init方法中,self指的是新创建的对象;在其他类方法中,它指的是调用其方法的实例。

Python不会强迫你使用"自我"。您可以给它起任何您想要的名称。但请记住方法定义中的第一个参数是对对象的引用。Python为您将self参数添加到列表中;您在调用方法时不需要包含它。如果您没有在init方法中提供self,那么您将收到错误

TypeError: __init___() takes no arguments (1 given)

init方法有什么作用?为什么它是必要的?(等)

init是初始化的缩写。它是一个构造函数,当你创建类和这是没有必要的的实例时被调用。但通常我们的做法是编写init方法来设置对象的默认状态。如果你一开始不愿意设置对象的任何状态,那么你不需要编写这个方法。

Python__init__self它们是做什么的?

self做了什么?它是什么意思?它是强制性的吗?

__init__方法有什么作用?为什么它是必要的?(等)

给出的示例不正确,所以让我根据它创建一个正确的示例:

class SomeObject(object):
def __init__(self, blah):self.blah = blah
def method(self):return self.blah

当我们创建对象的实例时,会在创建对象后调用__init__来自定义对象。也就是说,当我们调用SomeObject并在下面调用'blah'(可以是任何东西)时,它会作为参数传递给__init__函数,blah

an_object = SomeObject('blah')

self参数是SomeObject的实例,将分配给an_object

稍后,我们可能想在此对象上调用一个方法:

an_object.method()

执行虚线查找,即an_object.method,将实例绑定到函数的实例,并且方法(如上所述)现在是“绑定”方法-这意味着我们不需要显式地将实例传递给方法调用。

方法调用获取实例,因为它是在虚线查找上绑定的,并且在调用时,然后执行它被编程为执行的任何代码。

隐式传递的self参数按照惯例称为self。我们可以使用任何其他合法的Python名称,但如果您将其更改为其他名称,您可能会被其他Python程序员玷污和攻击。

__init__是一个特殊的方法,在Python datamodel留档。它在创建实例后立即调用(通常通过__new__-尽管除非您对不可变数据类型进行子类化,否则不需要__new__)。

只是一个问题的演示。

class MyClass:
def __init__(self):print('__init__ is the constructor for a class')
def __del__(self):print('__del__ is the destructor for a class')
def __enter__(self):print('__enter__ is for context manager')return self
def __exit__(self, exc_type, exc_value, traceback):print('__exit__ is for context manager')
def greeting(self):print('hello python')

if __name__ == '__main__':with MyClass() as mycls:mycls.greeting()

$ python3 class.objects_instantiation.py__init__ is the constructor for a class__enter__ is for context managerhello python__exit__ is for context manager__del__ is the destructor for a class

类对象支持两种操作:属性引用和实例化

属性引用使用Python中所有属性引用的标准语法:obj.name.有效的属性名称是创建类对象时类命名空间中的所有名称。因此,如果类定义如下所示:

class MyClass:"""A simple example class"""i = 12345
def f(self):return 'hello world'

那么MyClass.iMyClass.f是有效的属性引用,分别返回一个整数和一个函数对象。类属性也可以赋值给,所以你可以通过赋值改变MyClass.i的值。__doc__也是一个有效的属性,返回属于类的docstring:“一个简单的示例类”。

类实例化使用函数表示法。只需假装类对象是一个无参数函数,它返回类的新实例。例如:

x = MyClass()

实例化操作(“调用”类对象)创建了一个空对象。许多类喜欢创建具有自定义为特定初始状态的实例的对象。因此一个类可以定义一个名为__init__()的特殊方法,如下所示:

def __init__(self):self.data = []

当类定义__init__()方法时,类实例化会自动为新创建的类实例调用__init__()。所以在这个例子中,可以通过以下方式获得一个新的初始化实例:

x = MyClass()

当然,__init__()方法可能有参数以获得更大的灵活性。在这种情况下,给予类实例化运算符的参数将传递给__init__()。例如,

class Complex:def __init__(self, realpart, imagpart):self.r = realpartself.i = imagpart
x = Complex(3.0, -4.5)x.r, x.i

取自官方留档,最终对我帮助最大。


这是我的例子

class Bill():def __init__(self,apples,figs,dates):self.apples = applesself.figs = figsself.dates = datesself.bill = apples + figs + datesprint ("Buy",self.apples,"apples", self.figs,"figsand",self.dates,"dates.Total fruitty bill is",self.bill," pieces of fruit :)")

当你创建类Bill的实例时:

purchase = Bill(5,6,7)

你得到:

> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18  pieces of> fruit :)