zoukankan      html  css  js  c++  java
  • python 类

    一、类的简述

    类时面向对象编程的核心内容。通常把具有相同特征(数据元素)与行为(功能)的事物描述定义为一个类,类是一个抽象的概念,把类实例化既可以得到一个对象。

    因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。

    类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。

    对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。

    比如:把人类即为一个抽象的类,“老王”则为一个的人即对象。每个对象都有一些相同的特征,但具体的数值却不一定相同。如:每个人都有“姓名”,“国籍”,“年龄”等特征。还具有一些相同的行为,如:“吃饭”,“睡觉”,“工作”等

    可以简洁的描述为:Person ({"name", "country", "age"}, {"eat", "sleep", "work"})。

    在这里可以看到,类有两种属性:数据属性,行为属性。在类中行为属性一般称为“方法”。

    二、数据属性

    属性有两种,类属性,实例属性(对象的属性),通常把所有对象共同拥有的属性定义为类属性,如:每个人都只有两只眼等,实例属性则时根据不同的对象赋值不一样的值,如:姓名等

    下面来看一个简单的代码实现:

     1 class Person(object):
     2 
     3     eyes = 2
     4 
     5     def __init__(self, name, age):
     6         self.name = name
     7         self.age = age
     8 
     9     def eat(self, food):
    10         print("%s 吃:%s" % (self.name, food))
    11 
    12     def eye(self):
    13         print("%s" % (self.eyes))
    14 
    15 
    16 p1 = Person("张三", 18)
    17 p2 = Person("李四", 19)
    18 
    19 print("类的属性:", Person.__dict__)
    20 print("对象p1的属性:", p1.__dict__)
    21 print("对象p2的属性:", p2.__dict__)
    22 
    23 p1.eat("番茄炒鸡蛋")
    24 p1.eye()
    25 
    26 
    27 #输出结果
    28 类的属性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000002059BABB6A8>, 'eat': <function Person.eat at 0x000002059BABB730>, 'eye': <function Person.eye at 0x000002059BABBAE8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    29 对象p1的属性: {'name': '张三', 'age': 18}
    30 对象p2的属性: {'name': '李四', 'age': 19}
    31 张三 吃:番茄炒鸡蛋
    32 2
    View Code

    先输出,类, p1, p2 的属性,得出结论(1)实例化的对象只具备自己的数据属性(2)类的属性包含:类的数据属性、函数属性。

    这里要注意几点:

    1)方法的第一个参数不用传值,但必须在定义,因为python解释器,做了这样的一件事,自动把调用的对象当作第一个参数传值给方法,通常定义为self

    2)对象访问属性的过程,查找属性__dict__字典,找到就访问这个属性,当对象的属性字典不存在该属性时,则会去类属性里边找,类里边也不存在时则会报错

    3)类属性所有通过该类创建的对象都可以访问

    1、类属性的增删该查

     1 class Person(object):
     2     # 类属性添加的第一种方式
     3     eyes = 2
     4 
     5     def __init__(self, name):
     6         self.name = name
     7 
     8     def say(self, w):
     9         print("%s说了%s" % (self.name, w))
    10 
    11 
    12 print("1--类的属性:", Person.__dict__)
    13 
    14 # 类属性添加的第二种方式
    15 Person.arm = 2
    16 print("2--添加类的属性:", Person.__dict__)
    17 
    18 # 类属性修改
    19 Person.arm = 1
    20 print("3--修改类的属性:", Person.__dict__)
    21 
    22 # 类属性删除
    23 del Person.eyes
    24 print("4--删除类的属性:", Person.__dict__
    25 
    26 #输出结果
    27 1--类的属性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    28 2--添加类的属性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 2}
    29 3--修改类的属性: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 1}
    30 4--删除类的属性: {'__module__': '__main__', '__init__': <function Person.__init__ at 0x000001A8F769B6A8>, 'say': <function Person.say at 0x000001A8F769B730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'arm': 1}
    View Code

    看代码应该就差不多明白类属性的操作了。

    注:类属性一般一经定义,不会在执行的过程中增加、删除类的属性

    定义类属性一般只用第一种方法,其它的骚操作了解就好,忘了它吧

    2、实例属性的增删改查

     1 class Person(object):
     2 
     3     def __init__(self, name):
     4         # 实例属性添加第一种方式
     5         self.name = name
     6 
     7     def say(self, w):
     8         print("%s说了%s" % (self.name, w))
     9 
    10 
    11 p1 = Person("张三")
    12 p2 = Person("李四")
    13 print("1--p1的属性:", p1.__dict__)
    14 print("1--p2的属性:", p2.__dict__)
    15 
    16 # 实例属性添加第二种方式
    17 p1.age = 20
    18 print("2--p1的属性:", p1.__dict__)
    19 print("2--p2的属性:", p2.__dict__)
    20 
    21 # 删除实例属性
    22 del p1.name
    23 print("3--p1的属性:", p1.__dict__)
    24 print("3--p2的属性:", p2.__dict__)
    25 
    26 # 修改实例属性
    27 p1.age = 10
    28 print("4--p1的属性:", p1.__dict__)
    29 print("4--p2的属性:", p2.__dict__)
    30 
    31 
    32 # 输出结果
    33 1--p1的属性: {'name': '张三'}
    34 1--p2的属性: {'name': '李四'}
    35 2--p1的属性: {'name': '张三', 'age': 20}
    36 2--p2的属性: {'name': '李四'}
    37 3--p1的属性: {'age': 20}
    38 3--p2的属性: {'name': '李四'}
    39 4--p1的属性: {'age': 10}
    40 4--p2的属性: {'name': '李四'}
    View Code

    实例属性跟类属性的操作差不多。从上也可以得出结论,对对象 p1 的操作并不影响 p2 的属性。

    注:实例属性一般放在init方法里边初始化,不会在执行的过程中增加、删除对象的属性

    三、方法

    1、普通的方法

    上边没有@符号修饰,供外部实例调用,普通的方法也叫实例方法,但虽然叫实例方法但却与类相关,存储在类的属性中

    2、类方法

    上边有@classmethod修饰,定义时第一个参数必须为"cls",并通过cls来调用类属性,无法访问实例属性

    3、静态方法()

    上边有@staticmethod,与类相关但不需要访问属性,无法调用其它方法与属性

     1 class Person(object):
     2     eyes = 2
     3 
     4     def __init__(self, name):
     5         self.name = name
     6 
     7     def say(self, w):  # 普通方法
     8         print("%s say %s" % (self.name, w))
     9 
    10     @classmethod
    11     def cls_md(cls):  # 类方法
    12         print("这是类方法", cls.eyes)
    13 
    14     @staticmethod
    15     def stat():  # 静态方法
    16         print("这是静态方法")
    17 
    18 
    19 p1 = Person("zhangs")
    20 print(Person.__dict__)
    21 p1.say("hello")
    22 p1.cls_md()
    23 p1.stat()
    24 
    25 # 输出结果
    26 {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001DF5205B6A8>, 'say': <function Person.say at 0x000001DF5205B730>, 'cls_md': <classmethod object at 0x000001DF5205ABE0>, 'stat': <staticmethod object at 0x000001DF5205AEB8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    27 zhangs say hello
    28 这是类方法 2
    29 这是静态方法
    View Code

    4、方法的增(了解即可)

     1 class Person(object):
     2     eyes = 2
     3 
     4     def __init__(self, name):
     5         self.name = name
     6 
     7 
     8 def say2(self):  # 普通方法
     9     print("%s 增加普通方法" % (self.name))
    10 
    11 
    12 @classmethod
    13 def ha2(cls):  # 类方法
    14     print("增加类方法", cls.eyes)
    15 
    16 
    17 @staticmethod
    18 def stat2():  # 静态方法
    19     print("增加静态方法")
    20 
    21 
    22 print("增加前:", Person.__dict__)
    23 Person.say2 = say2
    24 Person.ha2 = ha2
    25 Person.stat2 = stat2
    26 print("增加后:", Person.__dict__)
    27 p1 = Person("zhangs")
    28 p1.say2()
    29 p1.ha2()
    30 p1.stat2()
    31 
    32 
    33 # 输出结果
    34 增加前: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001468207B6A8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    35 增加后: {'__module__': '__main__', 'eyes': 2, '__init__': <function Person.__init__ at 0x000001468207B6A8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'say2': <function say2 at 0x0000014681ECC1E0>, 'ha2': <classmethod object at 0x000001468207A390>, 'stat2': <staticmethod object at 0x000001468207AB70>}
    36 zhangs 增加普通方法
    37 增加类方法 2
    38 增加静态方法
    View Code

    四、私有化

    1、xx:公有变量

    2、_xx:单前置下划线,私有化属性或方法,类对象和子类可以访问,from module import * 禁止导入,但from module import _xx  或 Import module还可以导入

    3、__xx:双前置下划线,私有属性或方法,外部无法访问到(因为名字重整了,__xx变为_classname__xx),兼具_xx的特性

    4、__xx__:前后双下划线,用户名空间的魔法对象或属性,例如:__init__,一般不要自己定义这样的变量名

    5、xx_:单后置下划线,与python关键字重名+_区分,不要定义这样的变量名

  • 相关阅读:
    vue实现 toggle显示隐藏效果
    html+css奇淫技巧 3 教你如何伪类控制字体间距左右排版
    js 数组,字符串,json互相转换
    forEach 与for in
    js/jq 选项卡开发js代码
    html奇淫技巧 2 教你如何进行图文环绕布局 原创
    2019-05-07 开始记笔记vue
    vue src 拼接
    js 反选 全选看出你处于哪个阶段!
    JS获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度(转载)
  • 原文地址:https://www.cnblogs.com/yhongji/p/9582523.html
Copyright © 2011-2022 走看看