python tips:类与实例的属性问题

实例是具象化的类,它可以作为类访问所有静态绑定到类上的属性,包括类变量与方法,也可以作为实例访问动态绑定到实例上的属性。

实例1:

 1 class A:
 2     work = list("hello")
 3     kind = list("world")
 4     another = 1
 5
 6     def test1(self):
 7         print(self.work, self.kind, self.another)
 8         self.work[0], self.kind [0] = "t", "t"
 9         self.another += 1
10         print(A.work, A.kind, A.another)
11
12 if __name__ == "__main__":
13     a = A()
14     a.test1()

输出结果:

1 [‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘] [‘w‘, ‘o‘, ‘r‘, ‘l‘, ‘d‘] 1
2 [‘t‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘] [‘t‘, ‘o‘, ‘r‘, ‘l‘, ‘d‘] 1

test1中演示了实例对类变量的访问与修改,从输出结果可以看到,类变量work和kind的列表被修改了,而another的值没有发生变化,说明如果类变量是可变的,那么可以通过实例来对类变量进行修改,如果类变量不可变,那么实例无法修改类变量。

实例2:

 1 class A:
 2     work = list("hello")
 3     kind = list("world")
 4     another = 1
 5
 6     def test2(self):
 7         A.work, A.kind = "hello", " world"
 8         A.another += 2
 9         print(self.__dict__)
10         print(self.work, self.kind, self.another)
11         A.test2 = 13
12         print(self.test2)
13
14 if __name__ == "__main__":
15     a = A()
16     a.test2()

输出结果:

1 {‘another‘: 2}
2 hello  world 2
3 13

test2说明了实例访问类变量与方法的机制,在test1中,已经给实例动态绑定了一个another的属性,值为2(因为有赋值语句)。在self.__dict__中可以看到确实出现了实例属性another。

在使用实例访问属性(变量与方法)时,如果在实例的属性集里没有找到对应的属性,那么就会到类的属性集里找对应的属性。self.work和self.kind和类变量保持一致,说明并没有事先在实例与类变量之间建立引用,而是动态查找的。

 1 class A:
 2     work = list("hello")
 3     kind = list("world")
 4     another = 1
 5
 6     def test3(self):
 7         print(self.__dict__)
 8         self.w, self.k = 0, 1
 9         print(self.__dict__)
10         self.work, self.kind = 4, 4
11         print(self.__dict__)
12         self.test1 = 12
13         print(self.__dict__)
14         try:
15             self.test1()
16         except:
17             print("test1 is not a bound method")
18
19 if __name__ == "__main__":
20     a = A()
21     a.test3()

输出结果:

1 {‘another‘: 2}
2 {‘another‘: 2, ‘w‘: 0, ‘k‘: 1}
3 {‘another‘: 2, ‘w‘: 0, ‘k‘: 1, ‘work‘: 4, ‘kind‘: 4}
4 {‘another‘: 2, ‘w‘: 0, ‘k‘: 1, ‘work‘: 4, ‘kind‘: 4, ‘test1‘: 12}
5 test1 is not a bound method

self.__dict__中保存了动态绑定到实例的变量与方法,只要出现了赋值语句,都是动态绑定属性。如果动态绑定的属性与类的变量或方法同名,在查找过程中就会覆盖类的变量和方法。

总结

1. 动态绑定到实例的属性位于self.__dict__中

2. 出现self.attribute = XXX之类的赋值语句都是在往实例上动态绑定属性

3. 实例查找属性的流程:self.work   ->  self.__dict__["work"]  or  cls.work,这是一个动态的过程,实例中的同名属性会覆盖类变量或方法,类变量或方法的修改会实时影响实例查找属性的结果

4. 如果类变量是可修改的,如列表,字典等,可以通过实例来修改类变量,方法是不可修改的,故无法通过实例修改方法

原文地址:https://www.cnblogs.com/luoheng23/p/10988942.html

时间: 2024-10-03 17:34:53

python tips:类与实例的属性问题的相关文章

Python - 04182016 - 类与实例间属性的理解

Python是个很灵活的语言,光看它的类和实例间属性的访问机制就可以看出这一点,不过这一点还真的不好理解,做了些测试之后我的理解是这样的: 实例在访问类属性时,先检索自己的names, 如果有的话就直接取出,没有的话就去来的names里面找,找不到就是error啦 class Pclass(object): """docstring for Pclass""" num = 10 def __init__(self): super(Pclass,

python tips:类的绑定方法(bound)和非绑定方法(unbound)

类属性只有类及其实例能够访问,可以理解为一个独立的命名空间. Python中类属性的引用方式有两种: 1. 通过类的实例进行属性引用,称为绑定方法(bound method),可以理解为方法与实例绑定在一起. 2. 通过类进行属性引用,称为非绑定方法(unbound method),方法没有与实例绑定. 在绑定方法中,为了与实例绑定,Python自动将实例作为方法的第一个参数,而非绑定方法则表现的像普通函数,和普通函数的区别在于它只能通过类来访问. 两种引用方式: 1 class A: 2 de

python 面向对象整理 --------1.类和实例的属性

1.类的属性: # /usr/bin/env # coding = utf-8 class Chinese: #类的属性在这 country = 'China' def __init__(self, name): #实例的属性在这 self.name = name def play_ball(self, ball): print('%s正在打%s' % (self.name, ball)) #查看属性 print(Chinese.country) #修改属性 Chinese.country='J

python之---类和实例

类和实例: 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同. 仍以Student类为例,在Python中,定义类是通过class关键字: >>> class Student(object): ... pass ... >>> class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(obj

Python基础-类和实例

下文转载自廖雪峰大神的官方教程,非常感谢! 类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. 仍以Student类为例,在Python中,定义类是通过class关键字: class Student(object): pass class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object

Python—使用__slots__限制实例的属性

如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性. 为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性: class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 然后,我们试试: >>> s = Student() # 创建新的实例 >>> s.name = 'M

九、Python 一些类、实例、内建函数笔记

dir(Myclass)   用来展示一些类的内部属性还有方法,今天IBM面试问到了,居然忘记了,your sister. print Myclass.__dict__也可以 del c1清除一个引用 跟踪实例 class InstCt(object): count =0 def __init__(self): InstCt.count +=1 def __del__(self): InstCt.coutn -=1 def howMany(self): return InstCt.count [

python学习之类和实例的属性;装饰器@property

无论是类还是实例,一切皆是对象. Python是强动态语言,和java在这点上有所不同. class Ab(): a = 666 # 定义类对象Ab,自带属性a,值为666 # 使用Ab.__dict__可以查看类Ab的属性 us1 = Ab() us2 = Ab() # 定义两个实例对象us1.us2,这两个实例自身并不具备任何属性 # 只有在__init__中定义了self.arg=xxx的情况下,实例默认会具备arg属性 动态语言中,属性自带操作方法:获取(读).设置(写):还可以定义删除

python在类中使用__slot__属性

在类中定义__slot__属性来限制实例的属性字段,在创建大量对象的场合可以减少内存占用. 创建大量对象是内存占用对比: 类中不使用__slot__ class MySlot:def __init__(self, a, b, c): self.a = a self.b = b self.c = c @profile() def main(): myObj_list = list() for i in range(50000): myObj = MySlot(i, i, i) myObj_list