• [PY3]——面向对象编程(1)


    类的对象

    有三种对象

    可以做什么操作

    包括什么属性

    类对象

    属性引用、实例化

    函数方法、内置的属性、类变量

    实例对象

    属性引用

    函数方法、类变量、实例变量

    方法对象

    1. 类对象、实例对象、方法对象

    类[class]是抽象的模型
    实例[instance]是根据类创建出来的一个个具体的“对象”

    1.1  如何定义类

    class 类名(表示该类是从哪个类继承下来的): 
      xxx

    class ClassName:
        <statement-1>
        .
        .
        .
        <statement-N>

    1.2  属性引用

    class Myclass(object):
        '''A simple example about class'''
        i=123
        def f(self):
            return "hello world"
        def __init__(self,name,score):
            self.name=name
            self.score=score
    
    # 引用类变量、方法,都是合理的属性引用,分别返回一个整数和一个函数对象
    print(Myclass.i)
    123
    print(Myclass.f) ->这就叫做创建了方法对象,但要注意这只是创建了对象但不是调用了这个方法
    <function Student.f at 0x7f81f42c58c8>
    
    # 类还有内置的属性可以被引用
    print(Myclass.__doc__)
    A simple example about class
    print(Myclass.__name__)
    Myclass
    print(Myclass.__dict__)
    {'__doc__': 'A simple example about class', '__init__': <function Myclass.__init__ at 0x7f0bf8fd0950>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Myclass' objects>, 'i': 123, '__dict__': <attribute '__dict__' of 'Myclass' objects>, 'f': <function Myclass.f at 0x7f0bf8fd08c8>}
    print(Myclass.__module__)
    __main__
    print(Myclass.__bases__)
    (<class 'object'>,)
    内置类 描述
    __dict__ 类的属性
    __doc__ 类的文档字符串
    __name__ 类名
    __module__ 类定义所在的模块
    __bases__ 类的所有父类构成元素

    1.3 实例化操作

    # 实例化操作如下所示,赋值给一个变量,就能够创建一个实例对象
    x=Myclass()
    y=Myclass()
    print(x.i) 
    123
    print(x.f())
    hello world
    print(x.__doc__)
    A simple example about class

    # 创建的实例对象可以自由地绑定属性
    x.iii="a9a"
    print(x.iii)
    a9a
    # 创建的每个实例对象的内存地址都不一样
    print(x)
    <__main__.Myclass object at 0x7fbe7fa53160>
    print(y)
    <__main__.Myclass object at 0x7fbe7f7a8630>

    1.4 __init__

    # 上述的实例化操作创建了一个空的object
    # 但在很多情况下,我们创建实例对象时,可能都需要有特定的初始状态。这个由__init__方法实现。
    # 当一个类定义了 __init__() 方法, 类在实例化时会自动调用 __init__() 方法, 用于创建新的类实例
    
    class Myclass(object): '''A simple example about class''' i=123 def f(self): return "hello world" def __init__(self,name,score): self.name=name self.score=score # 关于__init__,要注意的是:
    (1) __init__方法的第一个参数永远是self,表示创建的实例本身

    (2) 有了__init__方法,在创建实例时就不能传入空的参数了,必须传入匹配的参数

    x=Myclass() TypeError: __init__() missing 2 required positional arguments: 'name' and 'score' x=Myclass("J",11) print(x.name,x.score) J 11

    2. 属性之“变量属性”、作用域问题、访问限制问题

    2.1  类变量、实例变量、作用域

    class test:
        x=7                    #类的直接下级作用域的变量,叫做类变量
    
        def __init__(self,name):
            self.name=name      #实例中的变量,叫实例变量
    
    
    instance1=test("name1")
    instance2=test('name2')
    
    # 类变量:既是类对象可见的属性、也是实例对象可见的属性
    print(test.x)
    7
    
    print(instance1.x)
    7
    
    # 下面的例子中,instance1.x+=100本质是实例对象instance1新建了一个属性,覆盖了instance1.x这个变量
    # 我们要知道,类变量可以是类对象的属性也可以是实例对象的属性,但实例对象的属性变化影响不了类对象的属性,也不会影响其他的实例对象
    # 反之,类对象属性的变化倒是能影响实例对象的属性
    test.x=100
    print(instance1.x)
    100
    print(test.x)
    100
    
    instance1.x+=100
    print(instance1.x)
    107
    print(test.x)
    100
    print(instance2.x)
    100

    2.2 访问限制

    # 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
    # 这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮
    
    class Student(object):
        def __init__(self,name,score):
            self.__name=name
            self.__score=score
    
    stu=Student('J',100)
    print(stu.__score)
    AttributeError: 'Student' object has no attribute '__score'
    
    
    # 如果要允许外部访问者两个变量,可以增加get方法(get_name()和get_score())
    # 如果又要允许外部修改这两个变量,可以增加set_score,虽然显得大费周折,但我们可以顺带对参数做个检查
    
    class Student(object):
        def __init__(self,name,score):
            self.__name=name
            self.__score=score
    
        def get_name(self):
            return '{}'.format(self.__name)
    
        def get_score(self):
            return '{}'.format(self.__score)
    
        def print_stu(self):
            print('%s:%s' % (self.__name,self.__score))
    
        def set_score(self,score):
            if 0<=score<=100:
                self.__score=score
            else:
                raise ValueError('bad score')
    
    
    stu=Student('J',100)
    print(stu.get_name())
    J
    print(stu.get_score())
    100
    stu.print_stu()
    J:100

    stu.set_score(
    99);print(stu.get_score()) 99 stu.set_score(101) ValueError: bad score

     3. 父类、子类(继承、多态)

    # 基类/父类/超类(base class/super class) <—— 子类(subclass)
    
    class Animal(object):
        def run(self):
            print("Animal is running...")
    
        def run2(self):
            print("111")
    
    class Dog(Animal):
        def run(self):
            print("Dog is running...")
    
    class Cat(Animal):
        def run(self):
            print("Cat is running...")
    
    animal=Animal()
    dog=Dog()
    cat=Cat()
    
    # 子类父类存在同名方法时,子类方法覆盖父类方法
    dog.run()
    Dog is running...
    dog.run2()
    111
    cat.run()
    Cat is running...
    
    # 可以通过isinstance(obj, class_or_tuple, /),可以判断一个instance object是否属于某个类
    print(isinstance(dog,Dog))
    True
    print(isinstance(dog,Animal))
    True
    print(isinstance(animal,Dog))
    False
    
    # issubclass(cls, class_or_tuple, /)class Base:
        Public_class_var='public class var'     #类变量(public)
        __Private_class_var='private class var' #类变量(private)
    
        def __init__(self):
            self.public_instance_var='public instance var'     #实例变量(public)
            self.__private_instance_var='private instance var' #实例变量(private)
    
        def public_instance_method(self):
            return 'public instance method'
    
        def __private_instance_method(self):
            return 'private instance method'
    
        @classmethod
        def public_class_method(cls):
            return 'public class method'
    
        @classmethod
        def __private_class_method(cls):
            return 'private class method'
    
        @staticmethod
        def public_static_method():
            return 'public static method'
    
        @staticmethod
        def __private_static_method():
            return 'private static method'
    
    class Sub(Base):
       pass
    
    sub=Sub()
    print(sub.__dict__)
    {'_Base__private_instance_var': 'private instance var', 'public_instance_var': 'public instance var'}
    
    # 子类可以继承类变量(public)、实例变量(public) class Sub(Base): def print_public_var(self): print(self.Public_class_var) def print_public_instance_var(self): print(self.public_instance_var) sub=Sub() sub.print_public_var() public class var sub.print_public_instance_var() public instance var # 事实上凡是公有的都能继承,凡是私有的都不能继承 class Sub(Base): def print_public_class_method(self): print(self.public_class_method()) def print_public_static_method(self): print(self.public_static_method()) def print_public_instance_method(self): print(self.public_instance_method()) sub=Sub() sub.print_public_class_method() public class method sub.print_public_static_method() public static method sub.print_public_instance_method() public instance method

     4. classmethod、staticmethod

    class A(object):
        def foo(self,x):
            print("executing foo({},{})".format(self,x))
    
        @classmethod
        def class_foo(cls,x):
            print("executing class_foo({},{})".format(cls,x))
    
        @staticmethod
        def static_foo(x):
            print("executing static_foo({})".format(x))
    
    a=A()
    
    a.foo(1)
    executing foo(<__main__.A object at 0x7fe8619c7160>,1)
    
    a.class_foo(1)
    executing class_foo(<class '__main__.A'>,1)
    
    a.static_foo(1)
    executing static_foo(1)
    
    a.static_foo('hi')
    executing static_foo(hi)
    
    A.class_foo(1)
    executing class_foo(<class '__main__.A'>,1)
    
    A.static_foo(1)
    executing static_foo(1)
    
    A.foo(1)TypeError: foo() missing 1 required positional argument: 'x'
    
    print(a.foo)
    <bound method A.foo of <__main__.A object at 0x7f57d0ba41d0>>
    
    print(a.class_foo)
    <bound method A.class_foo of <class '__main__.A'>>
    
    print(a.static_foo)
    <function A.static_foo at 0x7f71b0c89b70>

    参考文章

    《Python3文档——类》

    《极客学院——从零开始学python——类(3)》

    《廖雪峰——面向对象——访问限制》

  • 相关阅读:
    python:时间格式转化
    python:将时间戳格式化为yyyyMMdd hh:mm:ss
    Oracle 实现表中id字段自增长
    django:将query-set类型转为json类型
    mysql:获取某个表的所有字段
    Navicat连接Mysql8.0.11出现1251错误
    Java垃圾回收(GC)机制详解
    Mybatis学习总结(九)——查询缓存
    Mybatis学习总结(八)——延迟加载
    Mybatis学习总结(七)——调用存储过程
  • 原文地址:https://www.cnblogs.com/snsdzjlz320/p/7519931.html
Copyright © 2020-2023  润新知