Python 中的 __init__ 和 self 起什么作用?[重复]

2024-11-27 10:43:00
admin
原创
17
摘要:问题描述:我正在学习 Python 编程语言,遇到了一些我不完全理解的东西。使用如下方法:def method(self, blah): def __init__(?): .... .... 它做什么self?它是什么意思?它是强制性的吗?该方法的作用是什么__init__?为...

问题描述:

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

使用如下方法:

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

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

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

我认为它们可能是 OOP 构造,但我了解的不是很多。


解决方案 1:

在此代码中:

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__ method
a.method_a('Sailor!') # We only pass a single argument

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

解决方案 2:

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

__init__是类的构造函数。self参数指的是对象的实例(就像this在 C++ 中一样)。

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

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

x = Point(1,2)

self如果要将值与对象一起保留,则在对象的方法中使用参数非常重要。例如,如果您按__init__如下方式实现该方法:

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

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

注意:在此答案中,需要澄清一下“构造函数”一词的使用。从技术上讲,“构造函数”的职责在 Python 中分为两种方法。这些方法是__new__(负责分配内存)和__init__(如此处所述,负责初始化新创建的实例)。

解决方案 3:

一个简短的说明性例子

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

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

输出:

345
123

解决方案 4:

简而言之:

  1. self顾名思义,它引用自身——调用该方法的对象。也就是说,如果有 N 个对象调用该方法,那么self.a将引用 N 个对象中的每一个的变量的单独实例。想象一下a每个对象都有N 个变量副本

  2. __init__在其他 OOP 语言(如 C++/Java)中被称为构造函数。基本思想是,它是一种特殊方法,在创建该类的对象时会自动调用

解决方案 5:

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

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

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

然后MyClass.iMyClass.f是有效的属性引用,分别返回一个整数和一个函数对象。类属性也可以被赋值,因此你可以MyClass.i通过赋值来改变的值。__doc__也是一个有效的属性,返回属于该类的文档字符串:“一个简单的示例类”。

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

x = MyClass()

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

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

当类定义__init__()方法时,类实例化会自动__init__()为新创建的类实例调用。因此,在此示例中,可以通过以下方式获取新的已初始化实例:

x = MyClass()

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

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i

摘自官方文献,它最终对我帮助最大。


这是我的例子

class Bill():
    def __init__(self,apples,figs,dates):
        self.apples = apples
        self.figs = figs
        self.dates = dates
        self.bill = apples + figs + dates
        print ("Buy",self.apples,"apples", self.figs,"figs 
                and",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 :)

解决方案 6:

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

解决方案 7:

试试这个代码。希望它能帮助很多像我一样的 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_name
        print '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

解决方案 8:

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

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

self 参数

该方法接受的参数__init__是:

def __init__(self, arg1, arg2):

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

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

额外的参数从何而来?

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

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

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

这意味着__init__我们可以在方法中执行以下操作:

self.arg1 = arg1
self.arg2 = arg2

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

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

像这样的值被称为对象属性。这里该__init__方法设置了实例的 arg1 和 arg2 属性。

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

解决方案 9:

请注意,self实际上可以是任何有效的 Python 标识符。例如,我们可以轻松地从 Chris B 的示例中写出:

class A(object):
    def __init__(foo):
        foo.x = 'Hello'

    def method_a(bar, foo):
        print bar.x + ' ' + foo

并且其工作方式完全相同。不过建议使用 self,因为其他 Python 程序员会更容易识别它。

解决方案 10:

self是做什么的?它的含义是什么?它是强制性的吗?

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

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

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

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

init是初始化的缩写。它是一个构造函数,当您创建类的实例时会调用它,这不是必需的。但通常我们的做法是编写 init 方法来设置对象的默认状态。如果您最初不愿意设置对象的任何状态,则无需编写此方法。

解决方案 11:

  1. __init__就是我们所说的“构造函数”,这意味着它是一个函数,它将根据我们传递给它的参数中指定的指令以及给定的“蓝图” - 类来创建类的对象。

  • 注意:每当我们创建特定类的对象时,首先调用的函数是构造函数。

  1. self表示类范围内的对象。它本质上是一个占位符,可以帮助我们保持语法清晰,这样我们就可以知道何时访问属性,或者何时调用方法。

解决方案 12:

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

解决方案 13:

‘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"

解决方案 14:

这只是针对该问题的一个演示。

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 manager
hello python
__exit__ is for context manager
__del__ is the destructor for a class

解决方案 15:

在此代码中:

class Cat:
    def __init__(self, name):
        self.name = name
    def 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

解决方案 16:

# Source: Class and Instance Variables
# https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables

class MyClass(object):
    # class variable
    my_CLS_var = 10

    # sets "init'ial" state to objects/instances, use self argument
    def __init__(self):
        # self usage => instance variable (per object)
        self.my_OBJ_var = 15

        # also possible, class name is used => init class variable
        MyClass.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 above
    obj1 = MyClass()

    # PRINTS    15    (instance variable)
    print obj1.my_OBJ_var

    # PRINTS    20    (class variable, changed value)
    print MyClass.my_CLS_var


run_example_func()

解决方案 17:

这里,这个家伙写得非常好而且简单:https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-ientated-programming/

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

self那么,所有 Customer 方法中的 self 参数有什么用呢?它是什么?当然是实例!换句话说,withdraw 之类的方法定义了从某个抽象客户账户中提取资金的指令。调用 jeff.withdraw(100.0) 会将这些指令用于 jeff 实例。

因此,当我们说 def withdraw(self, amount): 时,我们的意思是,“这是你从 Customer 对象(我们称之为 self)和一个美元数字(我们称之为 amount)中提取资金的方式”。self 是被调用 withdraw 的 Customer 实例。这也不是我在打比方。jeff.withdraw(100.0) 只是 Customer.withdraw(jeff, 100.0) 的简写,它是完全有效的(即使不常见)代码。

init self 可能对其他方法有意义,但对于init呢?当我们调用init时,我们正在创建一个对象,那么怎么会已经有 self 了呢?Python 允许我们将 self 模式扩展到对象构造时,即使它并不完全合适。试想一下,jeff = Customer('Jeff Knupp', 1000.0) 与调用 jeff = Customer(jeff, 'Jeff Knupp', 1000.0) 相同;传入的 jeff 也是结果。

这就是为什么当我们调用init时,我们通过诸如 self.name = name 之类的语句来初始化对象。请记住,由于 self 是实例,因此这相当于说 jeff.name = name,这与 jeff.name = 'Jeff Knupp 相同。同样,self.balance = balance 与 jeff.balance = 1000.0 相同。在这两行之后,我们认为 Customer 对象已“初始化”并可供使用。

小心你__init__

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

解决方案 18:

Python__init__以及self它们的作用是什么?

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

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

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

class SomeObject(object):

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

    def method(self):
        return self.blah 

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

an_object = SomeObject('blah')

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

稍后,我们可能想要调用该对象上的方法:

an_object.method()

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

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

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

__init__是一种特殊方法,记录在 Python 数据模型文档中。它在实例创建后立即被调用(通常通过__new__- 虽然__new__除非您正在对不可变数据类型进行子类化,否则不需要)。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   649  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   0  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   0  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   0  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用