导航:首页 > 编程语言 > python类属性

python类属性

发布时间:2022-01-17 11:06:14

python中实例属性和类属性之间的关系

一般来说,在Python中,类实例属性的访问规则算是比较直观的。

但是,仍然存在一些不是很直观的地方,特别是对C++和Java程序员来说,更是如此。

在这里,我们需要明白以下几个地方:

1.Python是一门动态语言,任何实体都可以动态地添加或删除属性。
2.一个类定义了一个作用域。
3.类实例也引入了一个作用域,这与相应类定义的作用域不同。
4.在类实例中查找属性的时候,首先在实例自己的作用域中查找,如果没有找到,则再在类定义的作用域中查找。
5.在对类实例属性进行赋值的时候,实际上会在类实例定义的作用域中添加一个属性(如果还不存在的话),并不会影响到相应类中定义的同名属性。

下面看一个例子,加深对上述几点的理解:

复制代码
代码如下:

class A:
cls_i = 0
cls_j
= {}
def __init__(self):
self.instance_i =
0
self.instance_j =
{}

在这里,我们先定义类A的一个实例a,然后再看看类A的作用域和实例a的作用域中分别有什么:

复制代码
代码如下:

>>> a = A()
>>>
a.__dict__
{'instance_j': {}, 'instance_i': 0}
>>>
A.__dict__
{'__init__': , '__mole__': '__main__', 'cls_i': 0, 'cls_j': {},
'__doc__': None}

我们看到,a的作用域中有instance_i和instance_j,A的作用域中有cls_i和cls_j。

我们再来看看名字查找是如何发生的:

复制代码
代码如下:

>>> a.cls_i
0
>>>
a.instance_i
0

在查找cls_i的时候,实例a的作用域中是没有它的,却在A的作用域中找到了它;在查找instance_i的时候,直接可在a的作用域中找到它。

如果我们企图通过实例a来修改cls_i的值,那会怎样呢:

复制代码
代码如下:

>>> a.cls_i = 1
>>>
a.__dict__
{'instance_j': {}, 'cls_i': 1, 'instance_i': 0}
>>>
A.__dict__
{'__init__': , '__mole__': '__main__', 'cls_i': 0, 'cls_j': {},
'__doc__': None}

我们可以看到,a的作用域中多了一个cls_i属性,其值为1;同时,我们也注意到A作用域中的cls_i属性的值仍然为0;在这里,我们其实是增加了一个实例属性,并没有修改到类属性。

如果我们通过实例a操纵cls_j中的数据(注意不是cls_j本身),又会怎么样呢:

复制代码
代码如下:

>>> a.cls_j['a'] =
'a'
>>> a.__dict__
{'instance_j': {}, 'cls_i': 1, 'instance_i':
0}
>>> A.__dict__
{'__init__': , '__mole__': '__main__',
'cls_i': 0, 'cls_j': {'a': 'a'}, '__doc__': None}

我们可以看到a的作用域没有发生什么变化,但是A的作用域发生了一些变化,cls_j中的数据发生了变化。

实例的作用域发生变化,并不会影响到该类的其它实例,但是类的作用域发生变化,则会影响到该类的所有实例,包括在这之前创建的实例:

复制代码
代码如下:

>>> A.cls_k = 0

㈡ python 继承与类属性的使用

题主的注释是没有问题的。
子类继承父类后,会自动继承了父类的属性。如果在子类中修改了继承得来的类属性时(即B.count=200),并不会修改父类的对应的同名类属性(A.count)。以后只要是通过子类访问该属性,访问的都是子类的属性。
通过父类修改了父类属性后,子类访问该属性时,会访问父类修改后的属性值。当然前提是子类没有对该属性重新赋值过。

㈢ python类的属性有哪几种如何访问它们

属性的访问机制

一般情况下,属性访问的默认行为是从对象的字典中获取,并当获取不到时会沿着一定的查找链进行查找。例如a.x的查找链就是,从a.__dict__['x'],然后是type(a).__dict__['x'],再通过type(a)的基类开始查找。

若查找链都获取不到属性,则抛出AttributeError异常。

一、__getattr__方法

这个方法是当对象的属性不存在是调用。如果通过正常的机制能找到对象属性的话,不会调用__getattr__方法。

classA:
a=1
def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)
#output
1
__getattr__call
b

二、__getattribute__方法

这个方法会被无条件调用。不管属性存不存在。如果类中还定义了__getattr__,则不会调用__getattr__()方法,除非在__getattribute__方法中显示调用__getattr__()或者抛出了AttributeError。

classA:
a=1
def__getattribute__(self,item):
print('__getattribute__call')
raiseAttributeError

def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)

所以一般情况下,为了保留__getattr__的作用,__getattribute__()方法中一般返回父类的同名方法:

def__getattribute__(self,item):
returnobject.__getattribute__(self,item)

使用基类的方法来获取属性能避免在方法中出现无限递归的情况。

三、__get__方法

这个方法比较简单说明,它与前面的关系不大。

如果一个类中定义了__get__(),__set__()或__delete__()中的任何方法。则这个类的对象称为描述符。

classDescri(object):
def__get__(self,obj,type=None):
print("callget")

def__set__(self,obj,value):
print("callset")

classA(object):
x=Descri()

a=A()
a.__dict__['x']=1#不会调用__get__
a.x#调用__get__
如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:

㈣ python中类属性和实例属性的区别

今天一同事说踩了python的坑,
这确实是个“坑”
但是我觉得python之所以这样设计,就是明确要求写代码的人知道自己在写什么^
^
python的实例属性必须在__init__(self)
方法中定义,直接跟在类名后边定义的属性都默认是类属性(类似于c++的static变量)。
而python实例又可以灵活的随便增加属性,便出现了图片中看似诡异的现象。
---------------------------------
我们来看一下他的原代码:
你觉得输出会是什么?
结果是
model_path
分别是
"xx_model"

"oo_model"
而model_dict全都是第二次调用的结果,也就是oo_model生成的dict的值(注意,他前边有一句self.model_dict.clear()

原因是什么呢?
"坑"
就在
他是用self.xxxx
这种方式引用变量,而不是self.__class__.xxxx
(1)
self.model_path=path;
#这对self.model_path进行了赋值,python中的第一次赋值视为变量的定义!
(2)
self.xxxx这种格式的第一次赋值含义是什么呢?-->含义是:定义,也就是说定义了一个名为xxxx的实例属性。
(3)
因此m1,m2的两次调用,分别定义了对应的(不同的)self.model_path属性。
而self.model_dict,从头到尾都是
引用
它,从未进行过
赋值(重定义),所以引用的都是
类属性

㈤ 请简单的说一下python类的属性和方法分别代表什么

代表类的共同属性和自己独特的属性!

㈥ python 一个类访问另一个类中的属性

你那个是定义的是实例属性,非类属性。如下定义类属性,即可按你的方式访问。

classA:
B=1

㈦ python类中的 方法 属性分别什么意思

就比方说有一个类叫做car

这个类的属性可以有colorsizebrandpriceyear等描述性的东西

这个类的方法可以是runstopforwardbackward等执行性的东西

classcar:
#定义基本属性
color=''
size=0
brand=''
price=0
year=0

#定义构造方法
def__init__(self):
self.color=color
self.size=size
self.brand=brand
self.price=price
self.year=year
defrun(self):
print("thecarisrunning")
defstop(self):
print("thecarisstop")
defforward(self):
print("thecarisforward")
defbackward(self):
print("thecarisbackward")

#类调用

benz=car('red',1.8T,'Mercedes',400000,2016)
benz.run()
benz.stop()
benz.forward()
benz.backward()

㈧ python 类属性为类时,如何进行赋值

因为b.name[0]
=
'zhang'修改的是类属性,类属性是全局的,所有的实例共享,如果想私有化,可以添加
def
__init__(
self
):
self.name
=
list(
self.name
)
就可以了.

㈨ python中类属性和类实例的属性的区别taoCMS

今天一同事说踩了python的坑, 这确实是个“坑”

但是我觉得python之所以这样设计,就是明确要求写代码的人知道自己在写什么^ ^

python的实例属性必须在__init__(self) 方法中定义,直接跟在类名后边定义的属性都默认是类属性(类似于c++的static变量)。

而python实例又可以灵活的随便增加属性,便出现了图片中看似诡异的现象。

---------------------------------

我们来看一下他的原代码:

你觉得输出会是什么?

结果是 model_path 分别是 "xx_model" 和 "oo_model"

而model_dict全都是第二次调用的结果,也就是oo_model生成的dict的值(注意,他前边有一句self.model_dict.clear() )

原因是什么呢? "坑" 就在 他是用self.xxxx 这种方式引用变量,而不是self.__class__.xxxx

(1) self.model_path=path; #这对self.model_path进行了赋值,python中的第一次赋值视为变量的定义!

(2) self.xxxx这种格式的第一次赋值含义是什么呢?-->含义是:定义,也就是说定义了一个名为xxxx的实例属性。

(3) 因此m1,m2的两次调用,分别定义了对应的(不同的)self.model_path属性。

而self.model_dict,从头到尾都是 引用 它,从未进行过 赋值(重定义),所以引用的都是 类属性

㈩ python中类的属性和方法的区别

属性是固有的性质,比如人的身高、性别
方法是可以进行的操作,比如人走路、骑车、打架、叫喊
属性和方法放在一起,就可以描述类了

阅读全文

与python类属性相关的资料

热点内容
跳转收费系统源码 浏览:600
python3什么时候 浏览:706
惠州房车app哪个好 浏览:971
编译器查看内存 浏览:738
荣耀4a怎样加密短信 浏览:459
创建学生管理数据库的命令是什么 浏览:297
程序员渣女 浏览:30
androideclipse界面设计 浏览:350
向日葵传输桌面文件在哪个文件夹 浏览:97
linux怎么查看命令 浏览:99
linux设置可写权限 浏览:263
app为用户解决什么 浏览:824
微信营销pdf 浏览:915
舵机51单片机 浏览:715
驻波值命令 浏览:1003
易语言225编译器 浏览:234
苹果手机视频存储文件夹 浏览:453
剪映软件app怎么剪音乐 浏览:560
dos命令攻击 浏览:903
解压属于什么分类 浏览:283