Python中类属性与实例属性详解:方法与功能(实例方法、类方法、静态方法全面解析)

相关阅读

Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482


        Python是一门面向对象的编程语言,其核心概念之一是类。类是对象的蓝图或模板,定义了对象的属性和方法。理解类的属性和方法对于掌握Python编程至关重要。本文将深入探讨Python中的类的属性和方法,帮助读者全面掌握这一重要主题。

1、类和实例

        在Python中,类是使用class关键字定义的。类定义了对象的属性和方法,实例是类的具体实现。下面是一个简单的类定义示例:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建类的实例
person1 = Person("Alice", 30)

        在这个例子中,Person类有两个属性(name和age)。__init__()方法是类的构造方法,在创建类的实例时会自动调用。

2、类的属性

        类的属性可以分为两类:实例属性和类属性。

实例属性

        实例属性是绑定到实例上的属性,每个实例都有独立的实例属性。实例属性通常在__init__()方法中定义:

class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model

car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Civic")

        在这个例子中,car1和car2是两个独立的实例,各自有独立的make和model属性。

类属性

        类属性是绑定到类本身的属性,所有实例共享一个类属性。类属性通常在类体内定义:

class Dog:
    species = "Canis lupus familiaris"

    def __init__(self, name):
        self.name = name

dog1 = Dog("Buddy")
dog2 = Dog("Max")

print(dog1.species)  # 输出:Canis lupus familiaris
print(dog2.species)  # 输出:Canis lupus familiaris

        在这个例子中,species是一个类属性,所有Dog类的实例共享这个属性。 

3. 类的方法

        类的方法是绑定到类或实例的函数。根据绑定方式的不同,类的方法可以分为实例方法、类方法和静态方法。

实例方法

        实例方法是绑定到实例上的方法,第一个参数通常命名为self(建议不更改),一般表示实例本身:

class Cat:
    def __init__(self, name):
        self.name = name

    def meow(self):
        print(f"{self.name} says meow.")

cat1 = Cat("Whiskers")
cat1.meow()  # 输出:Whiskers says meow.

类方法

        类方法使用@classmethod装饰器修饰,绑定到类而不是实例(但实例也可以访问它),第一个参数通常命名为cls(建议不更改),表示类本身:

class Bird:
    species = "Aves"

    def __init__(self, name):
        self.name = name

    @classmethod
    def set_species(cls, species):
        cls.species = species

bird1 = Bird("Sparrow")
Bird.set_species("NewSpecies")

print(bird1.species)  # 输出:NewSpecies

静态方法

        静态方法使用@staticmethod装饰器修饰,静态方法通常用于逻辑上属于类但不需要访问实例或类属性的方法: 

class Math:
    @staticmethod
    def add(a, b):
        return a + b

result = Math.add(5, 3)
print(result)  # 输出:8

4. 特殊情况

实例方法的非绑定调用

        上面所说的实例方法的调用是绑定式调用,即对于实例方法,使用了相应的实例调用。这并不是Python强制要求的,下面将举例说明。

​class Cat:
    def __init__(self, name):
        self.name = name

    def meow(self):
        print(f"{self.name} says meow.")

cat1 = Cat("Whiskers")
# 利用“实例名.实例方法名”的形式绑定调用,无需要手动传递实例作为参数,会自动将实例作为实例方法的第一个位置参数传入
cat1.meow()     # 输出:Whiskers says meow.

# 利用“类名.实例方法名”的形式非绑定调用,需要手动传递实例作为参数
Cat.meow(cat1)       # 输出:Whiskers says meow.
Cat.meow(self=cat1)  # 输出:Whiskers says meow.

        在进行非绑定调用时,需要手动传递实例对象,而对于绑定式调用,实例对象会自动传入并作为实例方法的第一个位置参数。

        实际上,在进行非绑定调用时,传入的甚至可以不是该类的实例,如下例所示。

class Cat:
    def __init__(self, name):
        self.name = name

    def meow(self):
        print(f"{self.name} says meow.")

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name} says bark.")

    def What(self):
        print(f"This is just like an {self}")

cat1 = Cat("Whiskers")
dog1 = Dog("Fido")
Cat.meow(dog1)        # 输出:Fido says meow.
Dog.bark(cat1)        # 输出:Whiskers says bark.
Dog.What("function")  # 输出:This is just like an function

        对于上例,只要传入bark方法的实例拥有name属性,传入meow方法的实例拥有name属性,就不会报错(这是因为方法中使用了传入对象的name属性)。对于What方法,传入的参数甚至没什么要求。

        这是个不建议的行为,因为它消除了实例方法和实例之间的绑定,甚至在某种意义上,该方法都不能称为实例方法了(因为可以像调用任何普通的函数一样调用它)。

        一个好的建议是:对于所有的实例方法,都使用实例绑定式调用。

类方法的实例调用

        上面所说的类方法的调用是绑定式调用,即对于类方法,使用了相应的类调用。这并不是Python强制要求的,一个类方法可以通过类的实例调用,下面将举例说明。 

class Bird:
    species = "Aves"

    def __init__(self, name):
        self.name = name

    @classmethod
    def set_species(cls, species):
        print(cls)
        cls.species = species

bird1 = Bird("Sparrow")
bird1.set_species("NewSpecies")
print(bird1.species) # 输出:<class '__main__.Bird'> NewSpecies

        对于静态方法,在通过绑定的类调用时,会自动将类作为静态方法的第一个位置参数传递,即使该类的实例调用静态方法, 也是如此。

        一个好的建议是:对于所有的类方法,都使用相应的类进行调用。

静态方法的实例调用\访问属性

        其实静态方法只代表着,不论是使用实例还是类,对其进行调用时,不会自动传递实例或类作为参数。不论是使用“实例名.实例方法名”还是“类名.实例方法名”,都需要手动传入参数。这也代表着静态方法其实也可以访问类或实例属性(尽管这不推荐),下面将举例说明。

class Math:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def mul(self):
        return self.x * self.y
    
math1= Math(2, 3)
result1 = math1.add(5, 3)
print(result1)  # 输出:8

result2 = Math.mul(math1)
print(result2)  # 输出:6

result3 = math1.mul(math1)
print(result3)  # 输出:6

        上例中的静态方法可以通过类的实例调用,也可以通过在使用类调用时传递实例来访问实例属性。

        一个好的建议是:对于所有的静态方法,使用相应的类进行调用,并且不要访问任何属性和方法。

总结

        本文总结了Python中类的属性(实例属性、类属性)和方法(实例方法、类方法、静态方法)相关的知识点,并在最后给出了一些特殊情况,这并不是鼓励去使用,只是为了更加严谨,避免”类方法不能访问实例属性“或”静态方法不能访问属性“之类的绝对说辞。 

作者:日晨难再

物联沃分享整理
物联沃-IOTWORD物联网 » Python中类属性与实例属性详解:方法与功能(实例方法、类方法、静态方法全面解析)

发表回复