一. 前言
- 在Python的面向对象编程中,类属性和实例属性是两个不同的概念,它们在作用域和使用方式上有所区别。
- Python中的面向对象编程中有三种方法:实例方法、类方法和静态方法,它们之间的差异主要体现在参数传递和调用方式上。
二. 面向对象 - 类属性和实例属性
在 Python 中,类属性和实例属性的区别在于它们的作用域不同。类属性属于类本身,在整个类中都是可见的;而全局属性是在所有的作用域中都是可见的。
1. 示例代码
class MyClass:
class_attr = "I am a class attribute"
def __init__(self, ins_attr):
self.ins_attr = ins_attr
if __name__ == '__main__':
obj1 = MyClass("I am an instance attribute of obj1")
obj2 = MyClass("I am an instance attribute of obj2")
print(obj1.class_attr) # 输出 "I am a class attribute"
print(obj2.class_attr) # 输出 "I am a class attribute"
print(obj1.ins_attr) # 输出 "I am an instance attribute of obj1"
print(obj2.ins_attr) # 输出 "I am an instance attribute of obj2"
obj1.class_attr = "I am a new update class attribute of obj1"
print(obj1.class_attr) # 输出 "I am a new update class attribute of obj1"
print(obj2.class_attr) # 输出 "I am a class attribute"
MyClass.class_attr = "I am a new MyClass attribute"
print(obj1.class_attr) # 输出 "I am a new update class attribute of obj1"
print(obj2.class_attr) # 输出 "I am a new MyClass attribute"
print(MyClass.class_attr) # 输出 "I am a new MyClass attribute"
上面的代码中,我们定义了一个 MyClass 类,其中有一个类属性 class_attr 和一个实例属性 name。在实例化 obj1 和 obj2 之后,我们分别访问了它们的实例属性和类属性,然后我们修改了类属性的值,并且分别访问了两个实例的类属性值,最后打印了每个实例的属性值。
运行结果如下
从以上运行结果可以看到,
- 当我们根据使用实例对象修改类属性时,该实例对象的类属性会改变,但只会作用于自身(修改的实例对象)。
- 当我们通过
类
直接修改类属性
时,类属性会发生改变,并且生效作用于其他的实例对象,其他的实例对象访问结果会变成类修改类属性后的结果,而实例对象修改过后的类属性却没有受到影响。
总结一下,类属性是一个类的全局变量,所有实例对象共享一个值,可以通过类名或实例对象访问;而实例属性属于实例对象私有的属性,每个实例对象都有自己的值,只能通过实例对象访问。在实际开发中,需要根据实际情况选择类属性和实例属性的使用
2. 常用的类属性装饰方式及用法
1. @property
将一个方法转换成属性,可以像访问属性一样访问。
class MyClass:
def __init__(self, value):
self._x = value
@property
def x(self):
return self._x
c = MyClass(5)
print(c.x) # 输出5
2. @classmethod
将一个方法声明为类方法,用类名调用。
class MyClass:
x = 0
@classmethod
def classmethod(cls):
cls.x += 1
return cls.x
print(MyClass.classmethod()) # 输出1
print(MyClass.classmethod()) # 输出2
3. @staticmethod
将一个方法声明为静态方法,可以不需要实例化对象就能够调用。
class MyClass:
@staticmethod
def staticmethod():
return "This is a static method."
print(MyClass.staticmethod()) # 输出"This is a static method."
4. @get.setter
用于设置属性值的方法,必须定义在@property方法下面。
class MyClass:
def __init__(self, value):
self._x = value
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value * 2
c = MyClass(5)
print(c.x) # 输出5
c.x = 10
print(c.x) # 输出20
5. @get.deleter
用于删除属性的方法,必须定义在@property方法下面。
class MyClass:
def __init__(self, value):
self._x = value
@property
def x(self):
return self._x
@x.deleter
def x(self):
del self._x
c = MyClass(5)
print(c.x) # 输出5
del c.x
# print(c.x) # AttributeError: 'MyClass' object has no attribute '_x'
6. @cached_property
缓存属性,只计算一次,后续访问直接返回缓存值。
from cached_property import cached_property
class MyClass:
@cached_property
def x(self):
print("Calculating x.")
return 5
c = MyClass()
print(c.x) # 输出Calculating x. 5
print(c.x) # 输出5
7.@lazy_attribute
在第一次访问该属性时才进行计算,之后返回缓存值。
from lazy_object_proxy import Proxy
class MyClass:
def __init__(self):
self._my_property = Proxy(self.calculate_my_property)
def calculate_my_property(self):
print("Calculating my_property!")
return 100
@property
def my_property(self):
return self._my_property
my_class = MyClass()
print(my_class.my_property) # Output: Calculating my_property! 100
print(my_class.my_property) # Output: 100
二. 面向对象 - 类方法,静态方法,实例方法
1. 实例方法:
在Python中,类中的所有函数默认都是实例方法,实例方法是将self
作为第一个参数的方法,它可以通过实例化一个对象来调用,它可以访问实例中的数据,也可以修改实例中的数据,最常用的方法之一。
示例代码
class MyClass:
def my_instance_method(self, arg1, arg2):
# 实例方法的代码
pass
instance = MyClass()
instance.my_instance_method(arg1, arg2)
2. 类方法:
类方法是将cls作为第一个参数的方法,它可以通过类名或对象名来调用,也可以修改类变量,但是它不能访问实例变量,类方法使用@classmethod
装饰器来定义。
示例代码
class MyClass:
class_var = 0
@classmethod
def my_class_method(cls, arg1, arg2):
# 类方法的代码
cls.class_var += 1
pass
MyClass.my_class_method(arg1, arg2)
3. 静态方法:
这种方法也是类成员方法,但它们不需要访问类或实例的上下文。静态方法可以像普通函数一样被调用,没有默认的参数。
静态方法不需要传递任何参数,它与类和实例无关,可以使用类名或对象名来调用,因此静态方法不能访问实例变量或类变量,静态方法使用@staticmethod
装饰器来定义。
class MyClass:
@staticmethod
def my_static_method(arg1, arg2):
# 静态方法的代码
pass
MyClass.my_static_method(arg1, arg2)
三. 总结:
- 实例方法是最常用的方法类型,只能被实例调用,第一个参数是
self
; - 类方法和静态方法都是类成员方法,可以通过类或实例调用;
- 类方法第一个参数是
cls
,表示当前类对象; - 静态方法没有默认参数,类的上下文不会传递给它。
以上就是关于python中面向对象的属性,类方法,静态方法,实例方法的区别及用法详解,希望对你有所帮助,请不吝你的三连,谢谢!