python愛玩客

跳到主文

不是不久的將來,已經是現在進行式,不論您是學生、家長、上班族、工程師、老師、老闆、藝術家,拜託大家都來學寫程式。我們學英文是為了增加外語能力,提升國際化;那學程式的目的就是培養及強化邏輯思考能力並裝備自己來面對數位化的未來。所以不論您是要升學、考試、就業、創業、家事料理、投資理財、經營事業,請先學學這人人必備的邏輯概念。我是來自金融產業的IT資深工程師,希望藉由新技術的學習,交流更多先進及同好 輕鬆分享學習,互相勵志並創造共同進步的新人生。也想留下一些紀錄,告訴認識我的人,除了稱呼之外,我的人生還能有些什麼奉獻!

部落格全站分類:生活綜合

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 8月 23 週四 201822:00
  • python 中self到底是幹嘛用的,一定要寫嗎,代表什麼意思,一定要搞懂嗎?

 

stackoverflow 真是寶庫, 眾多高手分享經驗及解答,讓問題能得到公開透明且大家可以討論的回答,現在的同學真幸福,碰到疑問一定要到這裡查查!

先說結論 養成一個好習慣,任何的class 宣告時,且習慣性的加入 def __init__(self,name1,name2,....):,讓它變成class宣告時的"起手式"
這邊代表宣告時會自動執行的函式
如上面的簡單範例1,在起手式添加了一個name屬性
所以在創造實體時,都必須要給這個屬性一個參數
才能成功創造實體

self代表类的实例,而非类。

实例来说明

class Test:
 def prt(self):
 print(self)
 print(self.__class__)

t = Test()
t.prt()

执行结果如下

<__main__.Test object at 0x000000000284E080>
<class '__main__.Test'>

从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。

self不必非写成self

有很多童鞋是先学习别的语言然后学习Python的,所以总觉得self怪怪的,想写成this,可以吗?
当然可以,还是把上面的代码改写一下。

class Test:
 def prt(this):
 print(this)
 print(this.__class__)

t = Test()
t.prt()

改成this后,运行结果完全一样。
当然,最好还是尊重约定俗成的习惯,使用self。

self可以不写吗

在Python的解释器内部,当我们调用t.prt()时,实际上Python解释成Test.prt(t),也就是说把self替换成类的实例。
有兴趣的童鞋可以把上面的t.prt()一行改写一下,运行后的实际结果完全相同。
实际上已经部分说明了self在定义时不可以省略,如果非要试一下,那么请看下面:

class Test:
 def prt():
 print(self)

t = Test()
t.prt()

运行时提醒错误如下:prt在定义时没有参数,但是我们运行时强行传了一个参数。
由于上面解释过了t.prt()等同于Test.prt(t),所以程序提醒我们多传了一个参数t。

Traceback (most recent call last):
 File "h.py", line 6, in <module>
 t.prt()
TypeError: prt() takes 0 positional arguments but 1 was given

当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。

class Test:
 def prt():
 print(__class__)
Test.prt()

运行结果如下

<class '__main__.Test'> 

在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。

先看代码

class Parent:
 def pprt(self):
 print(self)

class Child(Parent):
 def cprt(self):
 print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()

运行结果如下

<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>

解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt(c),所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。

在描述符类中,self指的是描述符类的实例

不太容易理解,先看实例:

class Desc:
 def __get__(self, ins, cls):
 print('self in Desc: %s ' % self )
 print(self, ins, cls)
class Test:
 x = Desc()
 def prt(self):
 print('self in Test: %s' % self)
t = Test()
t.prt()
t.x

运行结果如下:

self in Test: <__main__.Test object at 0x0000000002A570B8>
self in Desc: <__main__.Desc object at 0x000000000283E208>
<__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8> <class '__main__.Test'>

大部分童鞋开始有疑问了,为什么在Desc类中定义的self不是应该是调用它的实例t吗?怎么变成了Desc类的实例了呢?
注意:此处需要睁大眼睛看清楚了,这里调用的是t.x,也就是说是Test类的实例t的属性x,由于实例t中并没有定义属性x,所以找到了类属性x,而该属性是描述符属性,为Desc类的实例而已,所以此处并没有顶用Test的任何方法。
那么我们如果直接通过类来调用属性x也可以得到相同的结果。
下面是把t.x改为Test.x运行的结果。

self in Test: <__main__.Test object at 0x00000000022570B8>
self in Desc: <__main__.Desc object at 0x000000000223E208>
<__main__.Desc object at 0x000000000223E208> None <class '__main__.Test'>
153down vote

When objects are instantiated, the object itself is passed into the self parameter.

enter image description here

Because of this, the object’s data is bound to the object. Below is an example of how you might like to visualize what each object’s data might look. Notice how ‘self’ is replaced with the objects name. I'm not saying this example diagram below is wholly accurate but it hopefully with serve a purpose in visualizing the use of self.

enter image description here

The Object is passed into the self parameter so that the object can keep hold of its own data.

Although this may not be wholly accurate, think of the process of instantiating an object like this: When an object is made it uses the class as a template for its own data and methods. Without passing it's own name into the self parameter, the attributes and methods in the class would remain as a general template and would not be referenced to (belong to) the object. So by passing the object's name into the self parameter it means that if 100 objects are instantiated from the one class, they can all keep track of their own data and methods.

 

 
up voteLet's say you have a class ClassA which contains a method methodA defined as:
def methodA(self, arg1, arg2):
 # do something

and ObjectA is an instance of this class.

Now when ObjectA.methodA(arg1, arg2) is called, python internally converts it for you as:

ClassA.methodA(ObjectA, arg1, arg2)

The self variable refers to the object itself.

class A: 
 foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: [5]

class A: 
 def __init__(self): 
 self.foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: []

Take a look at the following example, which clearly explains the purpose of self

class Restaurant(object): 
 bankrupt = False

 def open_branch(self):
 if not self.bankrupt:
 print("branch opened")

#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False

#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True 
>>> y.bankrupt
True

>>> x.bankrupt
False 

self is used/needed to distinguish between instances.

The 'self' is a reference to the class instance

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

Now we can create an instance of foo and call the method on it, the self parameter is added by Python in this case:

f = foo()
f.bar()

But it can be passed in as well if the method call isn't in the context of an instance of the class, the code below does the same thing

f = foo()
foo.bar(f)

Interestingly the variable name 'self' is just a convention. The below definition will work exactly the same.. Having said that it is very strong convention which should be followed always, but it does say something about flexible nature of the language

class foo:
 def bar(s):
 print "hi"
1down vote

What does self do? What is it meant to be? Is it mandatory?

The first argument of every class method, including init, is always a reference to the current instance of the class. By convention, this argument is always named self.In the init method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called.

Python doesn't force you on using "self". You can give it any name you want. But remember that the first argument in a method definition is a reference to the object.Python adds the self argument to the list for you; you do not need to include it when you call the methods. if you didn't provide self in init method then you will get an error

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

 

 

462down vote

In this code:

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

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

... the self variable represents the instance of the object itself. Most object-oriented languages pass this as a hidden parameter to the methods defined on an object; Python does not. You have to declare it explicitly. When you create an instance of the A class and call its methods, it will be passed automatically, as in ...

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

The __init__ method is roughly what represents a constructor in Python. When you call A() Python creates an object for you, and passes it as the first parameter to the __init__ method. Any additional parameters (e.g., A(24, 'Hello')) will also get passed as arguments--in this case causing an exception to be raised, since the constructor isn't expecting them.

文章標籤
全站熱搜
創作者介紹
創作者 阿丹 的頭像
阿丹

python愛玩客

阿丹 發表在 痞客邦 留言(0) 人氣(12,699)

  • 全站分類:
  • 個人分類:
▲top

參觀人氣

  • 本日人氣:2
  • 累積人氣:38,799

誰來我家

個人資訊

阿丹
暱稱:
阿丹
分類:
生活綜合
好友:
累積中
地區:

熱門文章

  • ()python 中self到底是幹嘛用的,一定要寫嗎,代表什麼意思,一定要搞懂嗎?
  • ()善用tkinter的布局方法(pack、place、grid),讓您輕鬆規劃部件的位置及樣貌。
  • ()python 中 method function 到底有什麼不同???? 骨狗了半天 還不太確定是不是就醬??????
  • ()如何用Tkinter 的text、 scrollbar部件製作互動文字框功能
  • ()如何利用tkinter設計出一個讓用戶可以選擇項目而不需登打輸入的功能呢?
  • ()如何用Tkinter menu 及menubutton等部件製作功能選單
  • ()別爭了?電腦與人互動的介面是CLI介面或是GUI介面較適合?
  • ()用python GUI模組 tkinter 製作視窗,看的到的視窗產出及變化,好有感!
  • ()Python的Tkinter使用者介面設計工具-設計出富有專業感又讓使用者覺得友善系統的小秘密、大訣竅
  • ()有圖有真相,有產出有成就,我們就從如何運用Python內建的tkinter模組來設計友善的用戶使用介面來開始吧!

文章分類

  • 未分類文章 (1)
PIXNET Logo登入

最新文章

    最新留言

    動態訂閱

    文章精選

    文章搜尋

    留言板