Class attribute and object attribute definition
Everything in Python is an object, and each object may have multiple attributes. Python attributes have a unified management scheme.
The attributes of an object may come from its class definition, which is called a class attribute. Class attributes may come from the class definition itself, or may be inherited from the class definition.
The attributes of an object may also be defined by the object instance, called object attributes.
The properties of the object are stored in the __dict__
properties of the object .
What dir() returns is only a name class table of the attributes of the object, and it __dict__
returns a dictionary, whose key is the attribute name, and the key value is the data value of the corresponding attribute object.
The chicken class inherits from the bird class, and summer is an object of the chicken class.
class bird(object):
feather = True
class chicken(bird):
fly = False
def __init__(self, age):
self.age = age
test
summer = chicken(2)
>>> print(bird.__dict__) 类属性
{
'__dict__': <attribute '__dict__' of 'bird' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'bird' objects>, 'feather': True, '__doc__': None}
>>> print(chicken.__dict__) 类属性
{
'fly': False, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x2b91db476d70>}
>>> print(summer.__dict__) 对象属性
{
'age': 2}
When we have a summer object, we query the attributes of the summer object, chicken class, bird class, and object class respectively, we can know all the summer object, __dict__
and we can find all the attributes that can be called and modified through the object summer. The following two attribute modification methods are equivalent:
summer.__dict__['age'] = 3
summer.age = 5
Generate attributes on the fly
There may be dependencies between different attributes of the same object. When a property is modified, we hope that other properties that depend on that property will also change at the same time. At this time, we cannot __dict__
store attributes statically in a way. Python provides a variety of methods to generate attributes on the fly. One of them is called a property. Characteristics are special attributes. For example, we add a feature adult to the chicken class. When the age of the object exceeds 1, adult is True; otherwise, it is False:
Option 1 --> Slightly troublesome
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class chicken(bird):
fly = False
def __init__(self, age):
self.age = age
def getAdult(self):
if self.age > 1.0: self.adult = True
else: self.adult = False
Methods of obtaining attributes of adult objects
>>> summer = chicken(2) #实例化
>>> summer.getAdult() #调用getAdult()方法,给adult属性赋值
>>> summer.adult #获取adult属性
Option 2 --> Use ternary selection, which is less practical
class bird(object):
feather = True
class chicken(bird):
fly = False
def __init__(self, age):
self.age = age
self.adult = True if self.age > 1.0 else False
Methods of obtaining attributes of adult objects
>>> summer = chicken(2) #实例化
>>> summer.adult #获取adult属性
Scheme 3 uses property, which is more practical
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class bird(object):
feather = True
class chicken(bird):
fly = False
def __init__(self, age):
self.age = age
def getAdult(self):
if self.age > 1.0: return True
else: return False
adult = property(getAdult)
Methods of obtaining attributes of adult objects
>>> summer = chicken(2) #实例化
>>> summer.adult #获取adult属性
????
class num(object):
def __init__(self, value):
self.value = value
def getNeg(self):
return -self.value
def setNeg(self, value):
self.value = -value
def delNeg(self):
print("value also deleted")
del self.value
neg = property(getNeg, setNeg, delNeg, "I'm negative")
x = num(1.1)
print(x.neg)
x.neg = -22
print(x.value)
print(num.neg.__doc__)
del x.neg
The above num is a number, and neg is a feature used to represent the negative number of a number. When a number is determined, its negative number is always determined; and when we modify the negative number of a number, its value should also change. These two points are implemented by getNeg and setNeg. And delNeg means that if the feature neg is deleted, the operation that should be performed is to delete the attribute value. The last parameter ("I'm negative") of property() is the description document of the characteristic negative.
Option 4 Use a special method__getattr__
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class bird(object):
feather = True
class chicken(bird):
fly = False
def __init__(self, age):
self.age = age
def __getattr__(self, name):
if name == 'adult':
if self.age > 1.0: return True
else: return False
else: raise AttributeError(name)
Each feature needs to have its own processing function, and __getattr__
all real-time generated attributes can be processed in the same function. __getattr__
Different attributes can be processed according to the function name. For example, when we query the attribute name male above, raise AttributeError.
(There is also a __getattribute__
special method in Python for querying arbitrary attributes. It __getattr__
can only be used to query __dict__
attributes that are not in the system)
__setattr__
(self, name, value) and __delattr__
(self, name) can be used to modify and delete attributes. They have a wider range of applications and can be used for any attribute.
Other ways to generate attributes on the fly
Instantly generating properties can also use other methods, such as descriptor (the descriptor class is actually the bottom layer of the property() function, and property() actually creates an object of this class). If you are interested, you can read it further.
Scope of class attributes and object attributes
Class attributes:
- Public attributes, private attributes, built-in attributes
Object attributes:
- Public attributes, private attributes, built-in attributes, method variables, global variables
Depending on the attribute, the scope of action is also different. The following is an illustration and description:
class MyClass(object):
"""类公有属性:在类中使用self.var1调用,类外使MyClass.var1调用,
也可以通过实例调用 instance.var1"""
var1 = 'class public attr: var1'
"""类私有属性:在类中使用self.__var2调用, 类外使用
MyClass._MyClass__var2调用,也可以通过实例调用instance._MyClass__var2"""
__var2 = 'class private attr: __var2'
def method(self):
"""在方法method内有效"""
var3 = 'method local attr: var3'
print(var3)
"""对象公有属性:方法调用后生效,在类内方法间通过self.var4调用,
在类外通过instance.var4"""
self.var4 = 'object public attr: self.var4'
print(self.var4)
"""对象私有属性:方法调用后生效, 在方法间内通过self.__var5调用,
类内其他方法不可调用,在类外通过instance.__var5"""
self.__var5 = 'object private attr: self.__var5'
print(self.__var5)
def method2(self):
print(self.var1)
print(self.__var2)
print(self.var4)
"""通过类调用类属性"""
>>> MyClass.var1
'class public attr: var1'
>>> MyClass._MyClass__var2
'class private attr: __var2'
"""通过对象调用类属性"""
>>> obj = MyClass()
>>> obj.var1
'class public attr: var1'
>>> obj._MyClass__var2
'class private attr: __var2'
>>> obj.var4
'object public attr: self.var4'
>>> obj._MyClass__var5
'object private attr: self.__var5'
Summarize
__dict__
tiered storage properties. Each layer __dict__
only stores the new attributes of that layer. The subclass does not need to repeatedly store the properties in the parent class.
Instantly generating attributes is a concept worth understanding. In Python development, you may use this method to manage object attributes more reasonably.