Python是一类程序语言的C语言,因而特性是程序语言编程中的关键基本概念众所周知。在Python中,特性是与第一类密切相关的统计数据或表达式,它可用作叙述第一类的状况或犯罪行为。Python中的特性能是实例特性或类属性。
实例特性
实例特性是与类的每一实例密切相关的特性。那些特性一般来说在实例化时建立并增设。下列是两个实例类:
class Person: def init(self, name, age): self.name = name self.age = age
在那个类中,每一实例都具备name和age特性。在实例化第一类时,那些特性将被增设为提供更多的值。比如:
person1= Person(“Alice”,25)person2= Person(“Bob”,30)print(person1.name)# 输入:Aliceprint(person2.age)# 输入:30
在那个范例中,person1的name特性被增设为”Alice”,age特性被增设为25。反之亦然,person2的name特性被增设为”Bob”,age特性被增设为30。
类特性
类特性是与类这类密切相关的特性。它被大部份类的实例共享资源。下列是两个实例类:
class Person: species =”Homo sapiens” def init(self, name, age): self.name = name self.age = age
在那个类中,每一实例都具备name和age特性,但species特性是类特性。因而,大部份Person实例共享资源完全相同的species特性。比如:
person1= Person(“Alice”,25)person2= Person(“Bob”,30)print(person1.species)# 输入:Homo sapiensprint(person2.species)# 输入:Homo sapiens
在这个范例中,person1和person2的species特性都是”Homo sapiens”。
类特性能通过类这类或任何类的实例来访问和增设。比如:
Person.species =”Homo neanderthalensis”print(person1.species)# 输入:Homo neanderthalensisprint(person2.species)# 输入:Homo neanderthalensisperson1.species =”Homo erectus”print(person1.species)# 输入:Homo erectusprint(person2.species)# 输入:Homo neanderthalensis
在那个范例中,我们首先通过类这类将species特性增设为”Homo neanderthalensis”,然后通过person1实例将其增设为”Homo erectus”。由于species特性是类特性,因而那个更改会影响大部份Person实例,但由于person1实例现在具备自己的species特性,因而仅会影响person1实例的species特性。
访问和增设特性
要访问特性,能使用点运算符。比如,要访问person1的name特性:
print(person1.name)# 输入:Alice
要增设特性,也能使用点运算符。比如,要将person2的age特性增设为35:
person2.age =35print(person2.age)# 输入:35
如果您想要在增设特性时添加一些逻辑或约束条件,能使用特性装饰器。特性装饰器是一类特殊的装饰器,用作将方法转换为特性。下列是两个实例:
class Person: def init(self, name, age): self.name = name self.age = age @property def name(self): return self.name @name.setter def name(self, value): if not isinstance(value, str): raise ValueError(“Name must be a string”) self.name = value @property def age(self): return self.age @age.setter def age(self, value): if not isinstance(value, int): raise ValueError(“Age must be an integer”) if value <0: raise ValueError(“Age must be non-negative”) self.age = value
在那个类中,name和age特性是用@property装饰器定义的。@property装饰器将方法转换为特性,使其在访问时看起来像两个普通特性。@name.setter和@age.setter装饰器定义了用作增设特性的方法。
在那个实例中,name特性只接受字符串值,而age特性只接受非负整数值。如果传递了无效的值,将会引发ValueError异常。
比如:
person = Person(“Alice”,25)person.name =”Bob”person.age =30print(person.name)# 输入:Bobprint(person.age)# 输入:30person.name =100# 引发ValueError异常person.age =-5# 引发ValueError异常
在那个实例中,我们首先实例化了两个Person第一类,然后使用name和age特性增设第一类的特性。我们还尝试将name特性设置为两个整数值和将age特性增设为两个负数值,这两种情况都会引发ValueError异常,因为它违反了特性装饰器中定义的约束条件。
当你已经了解了Python中特性的基础基本概念之后,能继续学习下列一些更高级的特性相关的基本概念和技术。
特性的继承
在Python中,子类能继承父类的特性,并且能添加新的特性或者重写父类的特性。当子类继承父类的特性时,它将具备完全相同的名称和类型,但它的值能不同。
下列是两个实例,展示了如何在子类中继承父类的特性:
class Person: def init(self, name, age): self.name = name self.age = age class Employee(Person): def init(self, name, age, employeeid): super().init(name, age) self.employeeid = employeeid person = Person(“Alice”,25)employee = Employee(“Bob”,35,12345)print(person.name, person.age)# 输入:Alice 25print(employee.name, employee.age, employee.employeeid)# 输入:Bob 3512345
在那个实例中,我们定义了两个Person类和两个Employee类。Employee类继承了Person类,并添加了两个名为employeeid的新特性。在Employee类的构造表达式中,我们使用super()表达式调用了父类的构造表达式,以便将name和age特性初始化为相应的值。
静态特性和类方法
在Python中,静态特性是属于类而不是实例的特性。类方法是能直接通过类名调用的方法。这两个基本概念在Python中经常一起使用,因为它都是与类密切相关的。
下列是两个实例,展示了如何定义静态特性和类方法:
class Person: count =0 def init(self, name, age): self.name = name self.age = age Person.count +=1 @staticmethod def printhello(): print(“Hello!”)@classmethod def getcount(cls): return cls.count person1= Person(“Alice”,25)person2= Person(“Bob”,30)Person.printhello()# 输入:Hello!print(Person.getcount())# 输入:2
在那个实例中,我们定义了两个Person类,其中包含两个静态特性count,用作记录建立的实例的数量。在init方法中,我们将count特性递增。我们还定义了两个静态方法printhello,用作打印“Hello!”。最后,我们定义了两个类方法getcount,用作返回count特性的值。
在实例中,我们建立了两个Person实例,并通过Person类调用了静态方法和类方法。
特性的可见性
在Python中,没有明确的私有特性或私有方法的基本概念。但,Python有两个命名约定,用作表示特性或方法应该被视为私有的。私有特性或方法的名称应该以两个或多个下划线开头,比如name或method。虽然那些特性或方法仍然能从类的外部访问,但那些名称的前导下划线能防止它被意外修改或使用。
另外,Python还有两个特殊的命名约定,用作表示特性或方法应该被视为受保护的。受保护的特性或方法的名称应该以两个下划线开头,比如name或method。虽然那些特性或方法也能从类的外部访问,但它一般来说被视为只能被类及其子类使用的特性或方法。
下列是两个实例,展示了如何使用命名约定来表示私有和受保护的特性:
class Person: def init(self, name, age, email): self.name = name self.age = age self.email = email def getname(self): return self.name def getage(self): return self.age class Employee(Person): def init(self, name, age, email, employeeid): super().init(name, age, email) self.employeeid = employeeid def getemail(self): return self.email person = Person(“Alice”,25,””)employee = Employee(“Bob”,35,””,12345)print(person.name)# 输入:Aliceprint(person.getage())# 输入:25print(employee.name)# 输入:Bobprint(employee.getage())# 输入:35print(employee.getemail())# 输入:
在那个实例中,我们定义了两个Person类和两个Employee类。在Person类的构造表达式中,我们使用前导下划线来表示name和age特性应该被视为私有特性。我们还定义了两个名为getname的受保护方法,用作返回name特性的值。
在Employee类的构造表达式中,我们调用了父类的构造表达式,并添加了两个名为employeeid的新特性。在Employee类中,我们能从类的外部访问email特性,因为它没有使用前导下划线来表示私有特性。
特性的文档字符串
在Python中,特性能有文档字符串,用作叙述特性的用途、值的含义等。文档字符串应该在特性的定义下面,以三个引号开始和结束。下列是两个实例,展示了如何添加文档字符串:
class Person:”””Represents a person with a name and an age.””” def init(self, name, age): self.name = name self.age = age @property def name(self):”””The persons name.””” return self
在那个实例中,我们在name特性的定义下面添加了两个文档字符串,用作叙述特性的含义。我们还使用了两个装饰器@property来定义name特性的getter方法。该装饰器允许我们像使用特性一样使用name方法。
总结
在Python中,特性是一类定义在类中的变量,它允许我们封装统计数据和逻辑,并控制对它的访问。我们能使用@property装饰器来定义getter和setter方法,或者使用property()表达式来建立两个特性。特性能有文档字符串,用作叙述特性的用途和含义。此外,Python还有一些命名约定,用作表示特性或方法应该被视为私有的或受保护的。