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