Python __init__ and self what do they do?
我正在学习Python编程语言,我遇到了一些我不完全理解的问题。
方法如下:
1 2 3 4 | def method(self, blah): def __init__(?): .... .... |
我认为它们可能是OOP构造,但我不太了解。
在本代码中:
1 2 3 4 5 6 | class A(object): def __init__(self): self.x = 'Hello' def method_a(self, foo): print self.x + ' ' + foo |
…
1 2 | a = A() # We do not pass any argument to the __init__ method a.method_a('Sailor!') # We only pass a single argument |
是的,你是对的,这些是OOP结构。
1 2 3 4 | class Point: def __init__(self, x, y): self._x = x self._y = y |
当为对象分配内存时,调用
1 | x = Point(1,2) |
如果要将值与对象一起持久化,则必须在对象方法中使用
1 2 3 4 | class Point: def __init__(self, x, y): _x = x _y = y |
您的
一个简单的例子
希望它能有所帮助,下面是一个简单的示例,我用来理解类内声明的变量与
1 2 3 4 5 6 7 8 9 10 | class MyClass(object): i = 123 def __init__(self): self.i = 345 a = MyClass() print a.i 345 print MyClass.i 123 |
简而言之:
尝试此代码。希望它能帮助像我这样的C程序员学习py。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #! /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__ |
输出:
我自己也难以忍受。即使在阅读了这里的答案之后。
要正确理解
自参数
1 | def __init__(self, arg1, arg2): |
但实际上我们只传递了两个参数:
1 | instance = OurClass('arg1', 'arg2') |
额外的争论来自哪里?
当我们访问一个对象的属性时,我们通过名称(或引用)来访问它。这里的实例是对新对象的引用。我们使用instance.printargs访问实例对象的printargs方法。
为了从
每当调用方法时,对主对象的引用都作为第一个参数传递。按照惯例,您总是将第一个参数称为方法本身。
这意味着在
1 2 | self.arg1 = arg1 self.arg2 = arg2 |
我们在这里设置对象的属性。您可以通过执行以下操作来验证这一点:
1 2 3 | instance = OurClass('arg1', 'arg2') print instance.arg1 arg1 |
这样的值称为对象属性。这里,
来源:http://www.voidspace.org.uk/python/articles/oop.shtml init方法
注意,
1 2 3 4 5 6 | class A(object): def __init__(foo): foo.x = 'Hello' def method_a(bar, foo): print bar.x + ' ' + foo |
它的工作原理完全一样。然而,建议使用Self,因为其他的Python会更容易识别它。
基本上,在同一类中的多个函数中使用变量时,需要使用"self"关键字。至于init,它用于设置默认值,以防调用该类中的其他函数。
类对象支持两种操作:属性引用和实例化
属性引用使用标准语法用于python:obj.name中的所有属性引用。有效的属性名是创建类对象时类的命名空间中的所有名称。因此,如果类定义如下所示:
1 2 3 4 5 6 | class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world' |
那么,
类实例化使用函数表示法。假设class对象是一个无参数函数,它返回类的一个新实例。例如:
1 | x = MyClass() |
实例化操作("调用"类对象)创建一个空对象。许多类都喜欢使用定制为特定初始状态的实例创建对象。因此,类可以定义一个名为
1 2 | def __init__(self): self.data = [] |
当一个类定义一个
1 | x = MyClass() |
当然,
1 2 3 4 5 6 7 | class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart x = Complex(3.0, -4.5) x.r, x.i |
从最终帮助我的官方文件中获取。
这是我的例子1 2 3 4 5 6 7 8 9 | 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 :)") |
创建类清单实例时:
1 | purchase = Bill(5,6,7) |
你得到:
1 2 | > Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18 pieces of > fruit :) |
"self"是对类实例的引用
1 2 3 | class foo: def bar(self): print"hi" |
现在我们可以创建一个foo实例并对其调用方法,在这种情况下,python会添加self参数:
1 2 | f = foo() f.bar() |
但是,如果方法调用不在类实例的上下文中,也可以传入它,下面的代码执行相同的操作
1 2 | f = foo() foo.bar(f) |
有趣的是,变量名'self'只是一个约定。下面的定义将完全相同。虽然它是一种非常强的惯例,应该一直遵循,但它确实说明了语言的灵活性。
1 2 3 | class foo: def bar(s): print"hi" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # 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() |
在本代码中:
1 2 3 4 5 | class Cat: def __init__(self, name): self.name = name def info(self): print 'I am a cat and I am called', self.name |
这里,
1 2 | c = Cat('Kitty') c.info() |
上述陈述的结果如下:
1 | I am a cat and I am called Kitty |
只是一个问题的演示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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() |
1 2 3 4 5 6 | $ 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 |
Python
__init__ andself what do they do?What does
self do? What is it meant to be? Is it mandatory?What does the
__init__ method do? Why is it necessary? (etc.)
给出的示例不正确,因此让我基于它创建一个正确的示例:
1 2 3 4 5 6 7 | class SomeObject(object): def __init__(self, blah): self.blah = blah def method(self): return self.blah |
当我们创建对象的实例时,会调用
1 | an_object = SomeObject('blah') |
稍后,我们可能希望对此对象调用一个方法:
1 | an_object.method() |
进行点式查找,即
方法调用获取实例,因为它是在点式查找上绑定的,当被调用时,然后执行它被编程执行的任何代码。
根据惯例,隐式传递的
What does self do? What is it meant to be? Is it mandatory?
每个类方法(包括init)的第一个参数始终是对类的当前实例的引用。按照约定,此参数始终命名为self。在in it方法中,self引用新创建的对象;在其他类方法中,self引用其方法被调用的实例。
python不会强迫你使用"self"。你可以给它取任何名字。但请记住,方法定义中的第一个参数是对对象的引用。python为您将自变量添加到列表中;调用方法时不需要包含自变量。如果您没有提供self-in-init方法,那么您将得到一个错误
1 | TypeError: __init___() takes no arguments (1 given) |
What does the init method do? Why is it necessary? (etc.)
初始化的缩写。它是一个构造函数,当您创建类的实例时会被调用,这是不必要的。但通常我们的做法是编写init方法来设置对象的默认状态。如果您不愿意最初设置对象的任何状态,那么您不需要编写这个方法。
在这里,这家伙写得非常好和简单:https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/
请阅读以上链接作为对此的参考:
self ? So what's with that self parameter to all of the Customer
methods? What is it? Why, it's the instance, of course! Put another
way, a method like withdraw defines the instructions for withdrawing
money from some abstract customer's account. Calling
jeff.withdraw(100.0) puts those instructions to use on the jeff
instance.So when we say def withdraw(self, amount):, we're saying,"here's how
you withdraw money from a Customer object (which we'll call self) and
a dollar figure (which we'll call amount). self is the instance of the
Customer that withdraw is being called on. That's not me making
analogies, either. jeff.withdraw(100.0) is just shorthand for
Customer.withdraw(jeff, 100.0), which is perfectly valid (if not often
seen) code.init self may make sense for other methods, but what about init? When we call init, we're in the process of creating an object, so how can there already be a self? Python allows us to extend
the self pattern to when objects are constructed as well, even though
it doesn't exactly fit. Just imagine that jeff = Customer('Jeff
Knupp', 1000.0) is the same as calling jeff = Customer(jeff, 'Jeff
Knupp', 1000.0); the jeff that's passed in is also made the result.This is why when we call init, we initialize objects by saying
things like self.name = name. Remember, since self is the instance,
this is equivalent to saying jeff.name = name, which is the same as
jeff.name = 'Jeff Knupp. Similarly, self.balance = balance is the same
as jeff.balance = 1000.0. After these two lines, we consider the
Customer object"initialized" and ready for use.Be careful what you
__init__ After init has finished, the caller can rightly assume that the
object is ready to use. That is, after jeff = Customer('Jeff Knupp',
1000.0), we can start making deposit and withdraw calls on jeff; jeff is a fully-initialized object.