首页 > 其他分享 >面向对象和类

面向对象和类

时间:2022-10-13 19:57:15浏览次数:37  
标签:__ name self 面向对象 print class def

面向对象


面向对象,简单来说用类对一切对象进行描述的一种编程思维和方法.在这里就不多做介绍(因为我也只是意会到一点点).根据面向对象的概念,我们需要注意的几个概念:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.

  • 对象(Object):通过类定义的数据结构实例.对象包括两个数据成员(类变量和实例变量)和方法。

  • 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用.

  • 实例变量:定义在方法中的变量,只作用于当前实例.

  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。

  • 方法:类中定义的函数.

  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法.也称为父类和子类

  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写.

  • 实例化:创建一个类的实例,类到具体对象的过程

  • 属性: 不管是变量或者是方法,都称为属性.变量一般称为静态属性,方法称为动态属性

面向对象的三大特性

1, 封装: 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.

2, 继承: 让不同类型的对象获得其它类型对象的属性和方法.

3, 多态: 实现接口重用, 即可以不同类型对象使用相同的方法,也可以一个对象的相同方法在不同情形有不同的表现形式

类的封装,基本构成和使用

1, 创建类,先来看例子

class Test(object):
	'''class_doc'''
    class_var = 'class_var'

    def class_func(self):
        obj_var = 'obj_var'
        print(obj_var)
class		|	定类的关键字通常类的首字母使用大写
object		|	新式类的所有类的基类,经典类和新式类在后面阐述,python3中建议使用这种形式定义类
class_doc	|	类的文档,可以通过__doc__方法查看
obj_var		|	实例变量,需要对类进行实例化生成对象后,才能通过对象是属于具体实例的.静态属性
def		|	定义类方法的关键字,和普通函数作用相同.动态属性
self		|	类方法必须有的参数,代表的是实例自身
class_var	|	类变量,可以在外部直接调用,不需要先进行实例话

2, 实例化,在python中使用类似函数调用的方式实例化类,并没有其它语言中的特殊关键字

t1 = Test()
#t1 就是类Test的具体对象

3, 访问属性,同样是上例子

class Test(object):

    class_var = 'class_var'

    def obj_func(self):
        obj_var = 'obj_var'
        print(obj_var)

t1 = Test()
Test.class_var = 'modify from Test'
print(Test.class_var)
#print(Test.obj_func())

t1.class_var = 'modify from t1'
print('Test:',Test.class_var)
print(t1.class_var)
print(t1.obj_func())
#print(t1.obj_var)

我们可以发现几个情况:

  • (1)类变量不需要实例化可以访问,实例在实例化后会共用类变量,
  • (2)不能通过实例修改类变量,修改的自身的那份类变量.相当于新生成了一个实例变量.
  • (3)类里定义的方法通常没有实例化,是不能访问.
  • (4)类方法里定义的实例变量是不能在外部直接调用的.

4, 类的内置方法,可以查看一些类的基本信息.(有些属性实例不能使用.)

__init__		|	构造方法
__del__			|	析构函数
__name__		|	查看类名
__dict__		|	查看类属性成员 
__doc__			|	查看类文档
__class__		|	查看对象所属的类
__module__		|	查看对象所在模块
__bases__		|	查看基类
__mro__			|	查看继承顺序
__call__		|	让实例化的对象可调用(即可以加执行符号())
__str__			|	打印对象是,返回这个方法的值,通常用在实例化的对象定制信息
__getitem__		|	见第9小点
__setitem__		|	见第9小点
__delitem__		|	见第9小点
__new__			|	实例化方法
__slots__		|	限制类属性
__metaclass__	        |	查看元类

5, 构造函数,类的实例化时执行的函数,通常用来实现对象的初始化.init_

class Test():
	name = 'class_var'
    def __init__(self,name,choice=None):
        self.name = name
        self.choice = choice

        if self.choice == 'yes':
            self.say_hello()
        else:
            self.other()

    def say_hello(self):
        print('Welcome,%s'%self.name)
    def other(self):
        print('No choice')

t1 = Test('sylar','yes')
print(t1.name)
#Test.name
t2 = Test('tom')

通过这个例子可以发现,构造函数中定义的属性是针对实例本身,并且也印证了类中的关键字self是指对象而不是类

6, 析构函数,del()也是可选的,如果不提供,则Python 会在后台提供默认析构函数.在对象销毁时自动执行的函数,显示的执行可以使用del obj

import time

class del_test(object):

    def say_bye(self):
        print('see you next time')

    def __del__(self):
        self.say_bye()

o1 = del_test()
del o1
time.sleep(3)
o2 = del_test()

7, 私有属性,无法在外部调用,但是可以在内部调用,从而隐藏某些属性或方法.

class Test(object):
    def __init__(self,name,id_status):
        self.name = name
        self.__status = id_status

    def show_status(self):
        print(self.__status)

t1 = Test('sylar','some info')
t1.show_status()
t1.__status

单下划线、双下划线、头尾双下划线说明:

foo: 定义的是特殊方法,一般是系统定义名字,类似\ init() 之类的.

_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了.

8, __call__方法,让不可执行的对象变的可执行

class Animal(object):
    def __call__(self, *args, **kwargs):
        print('call func')

t = Animal()
t()
Animal()()

9, getitem,setitem,delitem.用类模拟类似字典的操作

class Test(object):
    def __getitem__(self,key):
        print('__getitem__:',key)
    def __setitem__(self, key, value):
        print('__setitem__:',key,value)
    def __delitem__(self, key):
        print('__delitem__:',key)
t1 = Test()
t1['name']
t1['name'] = 'sylar'
del t1['name']

类的继承

1, 继承,代码重用,派生类(子类)会完全继承基类(父类)的所有属性.

class Base_Class(object):
    def __init__(self,name):
        self.name = name
        self.say_hi()
    def say_hi(self):
        print('Welcome, %s!'%self.name)
    def call_me(self):
        print("%s"%self.name)

class Sub_Class(Base_Class):
    pass

t1 = Sub_Class('sylar')
t1.call_me()

2, 方法重写: 当子类中定义的属性或方法和父类重名时,子类会覆盖父类中的定义.有些时候需要父类的方法,又需要做一些改动.可以直接在子类中调用父类的方法然后再添加新的代码,或者使用super函数.(建议使用super)

class Base_Class(object):
    def __init__(self,name):
        self.name = name
    def call_me(self):
        print("%s"%self.name)

class Sub_Class(Base_Class):
    def call_me(self):
        #super(Sub_Class,self).call_me()
        Base_Class.call_me(self)
        print('modify for Sub_Class')


t1 = Sub_Class('sylar')
t1.call_me()

3, 多继承顺序,又分为经典类和新式类,在python3中默认都是使用广度优先. 使用__mro__方法可以查看继承的查找顺序

class Base_A:
    def __init__(self):
        print('from A')

class Base_B(Base_A):
    pass

class Base_C(Base_A):
    def __init__(self):
        print('from C')

class Sub_Class(Base_B,Base_C):
    pass

t1 = Sub_Class()
print(Sub_Class.__mro__)

这段经典类的代码在python2X 输出为'from A'深度优先,在python3x输出为'from C'广度优先
python2 的新式类使用的广度优先

类的多态
接口重用,使用统一的接口对子类的方法进行调用

class Animal(object):
    @staticmethod
    def run_func(obj):
        obj.run()

class Cat(Animal):
    def run(self):
        print('Cat is running')

class Mouse(Animal):
    def run(self):
        print('Mouse is running')

c1 = Cat()
m1 = Mouse()
Animal.run_func(c1)
Animal.run_func(m1)

类内置装饰器

1, 静态方法 staticmethod不能访问类和实例属性,相当于和类本身没有什么关系,只是需要通过类名来调用这个方法.而且实例化后self也不会被传入到这个方法中.前面的多态就是一种使用场景.

2, 类方法 classmethod只能访问类变量不能访问实例变量

class Animal(object):
    name = 'Tom'
    def __init__(self):
        self.name = 'Jerry'

    @classmethod
    def run_func(self):
        print('%s is running'%self.name)

t = Animal()
t.run_func()

3, 属性方法 把一个方法当作静态属性来使用

单独使用,不能传参数

class Animal(object):
    def __init__(self):
        self.name = 'Jerry'

    @property
    def run_func(self):
        print('%s is running'%self.name)

t = Animal()
t.run_func

配合setter接受赋值,实现类似传入参数的功能

class Animal(object):
    def __init__(self):
        self.__who = None

    @property
    def run_func(self):
        print('%s is running'%self.__who)

    @run_func.setter
    def run_func(self,who):
        #print('set to name',who)
        self.__who = who

配合deleter删除,默认property装饰器转换过来的属性是不能删除的.如果要删除就要使用deleter

class Animal(object):
    def __init__(self):
        self.__who = None

    @property
    def run_func(self):
        print('%s is running'%self.__who)

    @run_func.setter
    def run_func(self,who):
        #print('set to name',who)
        self.__who = who
    @run_func.deleter
    def run_func(self):
        del self.__who
        
t = Animal()
t.run_func = 'Tom'
t.run_func
del t.run_func

类的定制(元类)和type

由于python是解释型语言,所以函数和类的定义不是编译时定义的,而是运行时动态创建的.在python中所有的类都是继承object,并由type方法生成的.type接收三个参数:类名,继承的父类元组,需要绑定的函数. 就可以生成一个类

def my_init(self,name):
    self.name = name

def say_hi(self):
    print('Hello %s'%self.name)

Test = type('Test', (object,), {'say_hi' : say_hi, '__init__' : my_init,})
t = Test('sylar')
t.say_hi()

1, __new__类的实例化方法,在所有类实例化的时候都是通过new方法

class MyClass(object):
    def __init__(self):
        print('some code in init!')

    def __new__(cls, *args, **kwargs):
        print('some code in new!')
        return object.__new__(cls)

t1 = MyClass()

new是执行在init之前的,并且通过return触发init的执行
return object.new(cls)相当于super去继承但这时候还没生成self,
cls相当于self,指代MyClass这个类的自身
2,metaclass元类,创建类的类,类是metaclass创建的实例.在python中自定义类需要先创建metaclass再创建类.python3和python2的语法有所改变

python3

def my_add(self,value):
    self.append(value)

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['my_add'] = my_add	#这里也可以使用lambda
        return type.__new__(cls, name, bases, attrs)

class MyList(list,metaclass=ListMetaclass):
    pass 

l1= MyList()
l1.my_add(1)
l1.my_add(2)
print(l1)

python2

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)

class MyList(list):
    __metaclass__ = ListMetaclass 

属性锁定

前面已经说了python类的属性可以动态创建的,为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class Test():
    #__slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age
t = Test('sylar',18)
t.job = 'it'

反射

判断类或实例是否有相应的属性,简单来说就是通过字符串来操作类.

hasattr(obj,name_str),判断对象里是否有对应字符串的属性

class Test():
    #__slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

t = Test('sylar',18)
choice = input()
res = hasattr(t,choice)
print(res)

getattr(obj,name_str),根据字符串获取对象相应的属性或是属性的内存地址

class Test():
    #__slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

t = Test('sylar',18)
choice = input()
res = getattr(t,choice)
print(res)

setattr(obj,name_str,attrs),根据字符串给对象设置相应的属性

class Test():
    #__slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

t = Test('sylar',18)
choice = input()
setattr(t,choice,'Tom')
v = getattr(t,choice)
print(t.name,v)

delattr(obj,name_str),删除字符串对应的属性

class Test():
    #__slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

t = Test('sylar',18)
choice = input()
delattr(t,choice)
print(t.name)

标签:__,name,self,面向对象,print,class,def
From: https://www.cnblogs.com/leeyong49/p/16789444.html

相关文章

  • 什么是面向对象?
    面向对象一、什么是类?类,就是具有共同特征的事物的抽象描述,这个描述分两种:特征描述和行为描述系统自带类:intstrdictfloatbool自定义类:编程时自己定义的clas......
  • 面向对象之多态
    鸭子类型我们都知道面向对象的语言有三大特性:封装、继承和多态,在这里我浅谈一下python的多态1classPageOne:2defstatus(self):3return"按期......
  • Python基础 - 面向对象
    面向对象基础入门,理解概念为主,其妙用需要很长时间去领悟哦.引入Python既是面向过程,也能面向对象.初学来理解为啥要面向对象,不太可能,用处......
  • 面向对象(上)01
    面向对象(上)01Java面向对象学习的三条主线:(第4-6章)1.Java类和类的成员:属性,方法,构造器;代码块,内部类.1.面向对象的三大特征:封装性,继承性,多态......
  • java--面向对象
    面向==对象==OO:OritenedObjectOOP:使用oo的思想进行开发。利用对象实现功能。  面向对象编程。1.封装2.继承3.多态   面向过程c vs 面向对象......
  • day08 final关键字&面向对象——多态&抽象类、方法&向上、向下转型
    day08final关键字最终的不可更改的特点:1)修饰类,类不能被继承2)修饰方法,方法不能被重写3)修饰成员变量(变为常量),值不能修改,名字大写,声明同时给常量赋值main方法中1)修饰......
  • python重拾第七天-面向对象进阶
    本节内容:面向对象高级语法部分经典类vs新式类静态方法、类方法、属性方法类的特殊方法反射异常处理Socket开发基础作业:开发一个支持多用户在线的FTP程序......
  • 22、面向对象(反射)
    22.1、反射介绍:1、什么是反射:(1)反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机......
  • 23、面向对象(包装)
    23.1、包装介绍:1、什么是包装(继承+派生):python为大家提供了标准数据类型以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改......
  • 24、面向对象(内置方法)
    24.1、isinstance(obj,cls)和issubclass(sub,super):1、isinstance(obj,cls):#isinstance(obj,cls)检查对象obj是否是类cls的对象classFoo(object):#object是类默认继承......