Python 中的 __init__ 和 self 起什么作用?[重复]
- 2024-11-27 10:43:00
- admin 原创
- 17
问题描述:
我正在学习 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
您的x
和y
参数将存储在堆栈上的变量中,并在 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:
简而言之:
self
顾名思义,它引用自身——调用该方法的对象。也就是说,如果有 N 个对象调用该方法,那么self.a
将引用 N 个对象中的每一个的变量的单独实例。想象一下a
每个对象都有N 个变量副本__init__
在其他 OOP 语言(如 C++/Java)中被称为构造函数。基本思想是,它是一种特殊方法,在创建该类的对象时会自动调用
解决方案 5:
类对象支持两种操作:属性引用和实例化
属性引用使用 Python 中用于所有属性引用的标准语法:obj.name。有效属性名称是创建类对象时类命名空间中的所有名称。因此,如果类定义如下所示:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
然后MyClass.i
和MyClass.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:
__init__
就是我们所说的“构造函数”,这意味着它是一个函数,它将根据我们传递给它的参数中指定的指令以及给定的“蓝图” - 类来创建类的对象。
注意:每当我们创建特定类的对象时,首先调用的函数是构造函数。
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__
将在创建对象后调用 来自定义对象。也就是说,当我们在下面调用SomeObject
with时'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__
除非您正在对不可变数据类型进行子类化,否则不需要)。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件