不弃_ 发表于 2022-2-21 19:02:06

self定义的变量

本帖最后由 不弃_ 于 2022-2-21 19:03 编辑

在类的方法中定义的变量带有self在所有方法中都能被直接调用吗?就相当于该变量的作用域是整个类。而普通函数的变量的作用域就是函数内部,在别的函数内部不能调用。

isdkz 发表于 2022-2-21 19:07:05

本帖最后由 isdkz 于 2022-2-21 19:09 编辑

类变量和实例变量都是跟类和实例绑定的,只要类和实例还存在就可以在任何地方使用,

函数里面定义的变量之所以不能在别的函数使用,只是进入到这个函数的调用栈里面就只执行这个函数的代码,出栈的时候这个函数就结束了,函数里面的变量自然就不存在了

不弃_ 发表于 2022-2-21 19:26:38

isdkz 发表于 2022-2-21 19:07
类变量和实例变量都是跟类和实例绑定的,只要类和实例还存在就可以在任何地方使用,

函数里面定义的变量 ...

你是说也能在类的外部使用?

isdkz 发表于 2022-2-21 19:32:44

本帖最后由 isdkz 于 2022-2-21 19:51 编辑


访问变量有两种类型:
1、全局与局部:(直接 XXX 访问)
在局部找不到,就到全局找

2、类与对象:(要以 XXX.XXX 的方式访问)
在对象中找不到,就到类中找

你可以看一下下面这两个代码:
class Test():
    a = 5
    def test(self):
      print("self: ", self)
      print("self.a: ", self.a)
      print("test: ", test)
      print("test.a: ", test.a)

a = Test()
a.test()    # 调用a的test方法,a的test方法打印 test 变量,因为局部没有,所以到全局找,全局没有,就报NameError了

class Test():
    a = 5
    def test(self):
      print("self: ", self)
      print("self.a: ", self.a)
      print("test: ", test)
      print("test.a: ", test.a)

test = Test()
test.test()   
""" 调用test对象的test方法,test对象的test方法打印 test 变量,因为局部没有,所以到全局找,

正如前面说的,它在局部中找不到是到全局中找的,而不会到类中找到 test 方法,因为属性和方法都是要用 XXX.XXX 的方式来访问的

找到了test对象并把它打印出来,可以看到test跟self是一样的,因为解释器会把它自身传给实例方法的第一个参数,也就是self,

所以在实例的方法里面可以通过 实例的名字来使用它的属性,就像上面的代码里面的 test.a,也可以使用self来使用它的属性,就像上面代码的 self.a,

但是实例在被实例化之前都不会知道它自己叫什么名字,就像第一段代码一样用了 a,test不存在,就报NameError了,所以在类里面定义它的方法的时候使用到它本身的变量都会用self,因为解释器会自动把self也就是调用者自身传入。"""

isdkz 发表于 2022-2-21 19:48:06

不弃_ 发表于 2022-2-21 19:26
你是说也能在类的外部使用?

对的,你在外部直接用 它的名字.属性(方法) 使用就行。你可以看一下我上面说的

不弃_ 发表于 2022-2-21 19:56:52

isdkz 发表于 2022-2-21 19:32
访问变量有两种类型:
1、全局与局部:(直接 XXX 访问)
在局部找不到,就到全局找


你的代码有一点小问题:class Test():
    a = 5
    def test(self):
      print("self: ", self)
      print("Test: ", Test)   #此处开头应大写
      print(Test.a)
print(Test.a)
a = Test()
a.test()
咱就是说能在类外面访问类中的变量是吧

isdkz 发表于 2022-2-21 20:01:47

不弃_ 发表于 2022-2-21 19:56
你的代码有一点小问题:
咱就是说能在类外面访问类中的变量是吧

不是,我要打印的就是实例,你看到后面就知道了,前面的的代码是为后面做铺垫的,

你也看一下注释,我有注释了的

isdkz 发表于 2022-2-21 20:08:28

不弃_ 发表于 2022-2-21 19:56
你的代码有一点小问题:
咱就是说能在类外面访问类中的变量是吧

我那个是为了给你演示为什么要用 self 的

不弃_ 发表于 2022-2-21 20:11:57

isdkz 发表于 2022-2-21 19:48
对的,你在外部直接用 它的名字.属性(方法) 使用就行。你可以看一下我上面说的

你看一下下面这段代码,提示说找不到x1
import random as r
import math
class Point:
    def __init__(self):
      self.x1 = r.randint(0,10)
      self.y1 = r.randint(0,10)

    def get_x(self):
      return self.x1
    def get_y(self):
      return self.y1


class Line(Point):
    def __init__(self):
       self.x = Point.get_x(self) - Point.get_x(self)
       self.y = Point.get_y(self) - Point.get_y(self)
       self.len = math.sqrt(self.x**2+self.y**2)


    def getlen(self):
      return self.len





a = Point()
b = Point()
tt = Line()
print(tt.len)

不弃_ 发表于 2022-2-21 20:19:07

isdkz 发表于 2022-2-21 19:48
对的,你在外部直接用 它的名字.属性(方法) 使用就行。你可以看一下我上面说的

不应该是类或对象+变量名访问变量

isdkz 发表于 2022-2-21 20:23:18

不弃_ 发表于 2022-2-21 20:11
你看一下下面这段代码,提示说找不到x1

因为你的Line虽然继承了Point,但是实例属性是在__init__方法里面初始化的,

你在Line中重写了__init__方法,你的Line中的__init__方法并没有初始化属性x1,

所以你重写方法的同时还想拥有父类方法的功能就要执行一下父类的初始化方法

import random as r
import math
class Point:
    def __init__(self):
      self.x1 = r.randint(0,10)
      self.y1 = r.randint(0,10)

    def get_x(self):
      return self.x1
    def get_y(self):
      return self.y1


class Line(Point):
    def __init__(self):
       Point.__init__(self)    # 加上这句,这里之所以手动传入self,是因为只有实例调用方法的时候才会自动传入self,类调用实例方法需要你自己传入
       self.x = Point.get_x(self) - Point.get_x(self)
       self.y = Point.get_y(self) - Point.get_y(self)
       self.len = math.sqrt(self.x**2+self.y**2)


    def getlen(self):
      return self.len





a = Point()
b = Point()
tt = Line()
print(tt.len)


isdkz 发表于 2022-2-21 20:26:22

不弃_ 发表于 2022-2-21 20:19
不应该是类或对象+变量名访问变量

我的意思就是

(类或对象的名字).(属性或方法的名字)

实例变量也叫属性,实例函数也叫方法

不弃_ 发表于 2022-2-21 20:31:52

isdkz 发表于 2022-2-21 19:32
访问变量有两种类型:
1、全局与局部:(直接 XXX 访问)
在局部找不到,就到全局找


[也就是说没加self的变量不能通过对象进行访问,加了self不仅能通过对象进行访问,还能通过类进行访问/b]

不弃_ 发表于 2022-2-21 20:33:56

isdkz 发表于 2022-2-21 20:26
我的意思就是

(类或对象的名字).(属性或方法的名字)


哦~

isdkz 发表于 2022-2-21 20:45:51

不弃_ 发表于 2022-2-21 20:31
[也就是说没加self的变量不能通过对象进行访问,加了self不仅能通过对象进行访问,还能通过类进行访问/b]

不是的,我只是想表示self也是跟实例名一样指向了实例的地址,

所以在实例里面既可以用实例的名字来访问实例自己的变量,也可以用self来访问,

只是你在定义类的时候你也不知道将来实例会用什么名,那不如就用self了

在这个实例产生了之后,你在全局里面也可以用 实例名.变量名 的方式给实例动态添加属性的

不弃_ 发表于 2022-2-21 20:53:25

不弃_ 发表于 2022-2-21 20:31
[也就是说没加self的变量不能通过对象进行访问,加了self不仅能通过对象进行访问,还能通过类进行访问/b]

不加self也能访问

不弃_ 发表于 2022-2-21 20:55:36

如果变量在方法内部是不能访问的,在外部可以

不弃_ 发表于 2022-2-21 21:01:03

isdkz 发表于 2022-2-21 20:45
不是的,我只是想表示self也是跟实例名一样指向了实例的地址,

所以在实例里面既可以用实例的名字来 ...

我知道self就是实例本身

isdkz 发表于 2022-2-21 21:02:02

不弃_ 发表于 2022-2-21 21:01
我知道self就是实例本身

好吧
页: [1]
查看完整版本: self定义的变量