Python class attributes and object attributes-definition and scope

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:

Insert picture description here

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.

Guess you like

Origin blog.csdn.net/qdPython/article/details/112787717