上个学期一直用python在刷codewars,写的都是小程序,也没用到类这些东西,这个学期要看一堆代码,发现对类的理解有点欠缺,所以来补一补。
属性:
python的类属性有两种。
第一种是类数据属性,可以通过类和实例来访问,被类所拥有。在类定义之后,可以通过类名进行添加,添加的类数据属性也可以被类和所有实例对象所访问和修改。
第二种是实例数据属性
以一个下划线开头,类似于 _xxx,属于类的私有属性(private),但是在定义类的文件中可以在类的外部访问到这类属性,这类属性的意思是尽管我可以直接访问,也请你要慎重使用。用import从外部引进该类时,不能直接访问该类的以一个下划线开头的私有属性。
以两个下划线开头,类似于 __xxx,属于类的私有变量(private),只有内部可以访问,外部不能访问。
以两个下划线开头,两个下划线结尾,类似于 __xxx__,可以被外部访问。
class Student(object): School = "" def __init__(self,name,grade,gender): self._name = name self.__grade__ = grade self.__gender = genderStudent.School = "XJTU"zh = Student("zh","Junior","female")print(Student.School,zh._name,zh.__grade__)print(zh.__gender)
运行结果:
zhuh@baojp-24000649:~/pra$ python3 class1.pyXJTU zh JuniorTraceback (most recent call last): File "class1.py", line 12, inprint(zh.__gender)AttributeError: 'Student' object has no attribute '__gender'
可以看出Student 中的 __gender不能在外部被访问,其他都可以被访问。双下划线开头的实例变量并不是完全不可以被外部访问,不能直接访问__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量,但是不同的解释器会有不同的更改方式。
方法:
一个类中有三种方法。
第一种是实例方法,定义实例方法时第一个参数必须是self,代表实例本身,实例方法只能通过实例来调用。
第二种是类方法,定义类方法时以cls作为第一个参数,cls表示类本身,定义时使用@classmethod装饰器。通过cls可以访问类的相关属性类方法可以通过类名访问,也可以通过实例访问。
第三种是静态方法,静态方法没有参数限制,既不需要实例参数,也不需要类参数,定义的时候使用@staticmethod装饰器。同类方法一样,静态法可以通过类名访问,也可以通过实例访问。
实例方法和类方法可以重载和继承,但是静态方法不可以继承,可以认为是全局函数。静态方法和类方法都只能对类属性进行操作,对实例属性不能操作。
class Student(object): //同前面一样 @staticmethod def print_info_s(): print(Student.School,Student._name,cls.__grade__,cls.__gender)Student.School = "XJTU"zh = Student("zh","Junior","female")zh.print_info_s()
运行结果
zhuh@baojp-24000649:~/pra$ python3 class1.pyXJTUTraceback (most recent call last): File "class1.py", line 22, inzh.print_info_s() File "class1.py", line 15, in print_info_s print(Student.School,Student._name,cls.__grade__,cls.__gender)AttributeError: type object 'Student' has no attribute '_name'
完整代码:
class Student(object): School = "" def __init__(self,name,grade,gender): self._name = name self.__grade__ = grade self.__gender = gender def print_info_c(self): print(self.School,self._name,self.__grade__,self.__gender) @classmethod def print_info_m(cls): print(cls.School) @staticmethod def print_info_s(): print(Student.School)Student.School = "XJTU"zh = Student("zh","Junior","female")zh.print_info_c()zh.print_info_m() Student.print_info_m() zh.print_info_s() Student.print_info_s()
运行结果
zhuh@baojp-24000649:~/pra$ python3 class1.pyXJTU zh Junior femaleXJTUXJTUXJTUXJTU