Python面向对象

大数据第26天-Python面向对象每次默认调用的方法是new,程序先调new再掉initinit可以完成参数赋值等一些基本的初始化工作init和new的参数要保持一致创建与删除对象init 创建对象当创建一个对象时,python解释器默认会调用一个方法,这个方法是: __init__()#给定默认值 xxxx 21def __init__(self,name="xxxx",...
摘要由CSDN通过智能技术生成

Python面向对象

每次默认调用的方法是new,程序先调new再掉init

init可以完成参数赋值等一些基本的初始化工作

init和new的参数要保持一致

创建与删除对象

init 创建对象
当创建一个对象时,python解释器默认会调用一个方法,这个方法是:  __init__()

#给定默认值 xxxx 21
def __init__(self,name="xxxx",age=21):
def __init__(self,*args,**kwargs):

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        # print("persion is running")
        print("%s is running" %self.name)
        
p = Person("zhangsan",18)
p.run()
    
    
    
class Animal:
# 对象初始化时调用
def __init__(self,name):
    self.name = name
    print(self.name+"来了")
# 创建对象,初始化 init方法调用
an = Animal("唐僧")
new 构造器
构造器__new__		构造器中的参数要和init中的参数一样,换而言之,无论什么情况init和new参数保持一致
一定要有返回值
				
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __new__(cls,name,age):
        cls.name = name
        cls.age = age
        return object.__new__(cls)
del 删除
  • 调用:
当删除一个对象时,
    python解释器也会调用一个方法,这个方法是:  __del__()
最后释放内存时调用
若多个对象n指向同一个类,则此时计数器的个数为n.
每次调用del方法时删除的是计数器的个数(n-1),也就是说每调用一次del就删除一下,计数器总个数-1
若计数器为1时再调用,则删除该对象
  • 案例:
class Animal:
    # 对象被回收时调用
    def __del__(self):
        print(self.name+"被妖怪抓走了")
# 手动删除对象,之后将不能在被使用,如果使用会报错
# del an
print(an.name)
# 如果没有手动删除,对象将在使用完才被系统收走
  • 案例:

    # 创建对象,初始化 init方法调用
    an = Animal("唐僧")
    # 手动删除对象,之后将不能在被使用,如果使用会报错
    an1 = an
    an2 = an
    print(id(an))
    print(id(an1))
    print(id(an2))
    print("马上删除对象an")
    del an
    print("马上删除对象an1")
    del an1
    print("马上删除对象an2")
    # 这句代码执行完毕,对象才会被真正删除(引用计数)
    del  an2
    
    • 引用计数:
    刚创建出来的时候为2,增加一个引用,引用计数+1,
    del  对象  ,可以减少引用计数,当引用计
    数为1时,在del 对象,才会真正被回收
    
魔法方法1—id
类似于java内存地址的值,用于判断对象是否是单例模式
#此时ip一样		  					 #此时id不一样
p1 = person(xxxxxxxx)				p1 = persion(xxxxxx)
p2 = p1								p2 = persion(xxxxxx)
print(id(p1))						print(id(p1))
print(id(p2))						print(id(p2))
魔法方法2—str
类似于java的toString打印的方法

共有/私有转换

# 私有方法
def test(self):
    print("调用test共有方法")

继承

单继承
  • 继承概念

    用来描述类与类之间的一种关系:
    父类、超类、基类
    子类、派生类
    
  • 继承的语法

    class  子类(父类名,...):
    方法...
    如果一个类没有明确指明父类,则它的父类为object
    
  • 案例:

    • 定义Cat类,包含属性: name,color,age;方法:eat() sleep() catchmouse()
    • 定义Dog类,包含属性: nage,color,age;方法:eat() sleep() lookafterHouse()
    • 发现许多重复的东西,优化,抽离一个父类Animal出来
  • 总结:

    • 子类可以继承父类中所有的属性跟方法(私有除外)
    • 私有属性不能通过对象直接访问,但可以通过方法访问
    • 私有方法,不能通过对象直接访问
  • 属性自动化赋值(高级用法)(setattr,getattr,hasattr,isinstance函数的使用)

    # 属性自动化赋值
    class Dog():
        def __init__(self,name,age,gender,color,breed):
            print(locals())
            # pass
            self.attributeFromdict(locals())
        # 自定义方法,设置属性
        def attributeFromdict(self,d):
            self = d.pop('self')
            for n, v in d.items():
                # 内置函数,为self的属性赋值value
                setattr(self,n,v)
        def showinfo(self):
            print(self.name)
            print(self.age)
            print(self.breed)
            print(self.gender)
    dog =Dog('aa',12,'男','red','京巴')
    dog.showinfo()
    
多继承
  • 概念

    所谓多继承,就是一个类同时有多个父类
    思考:狼狗的父类
    狼、狗
    
  • 语法

    class 子类(父类1,父类2):
    方法...
    如果父类1,父类2中都有属性,则以先继承的类为标准,如果两个父类存在同名方法,则一样
    以先继承的类为准,所有父类中的非同名方法都能被继承到
    
    若父类都有相同名的方法,则先调用(xx,oo)括号里前面的父类方法
    
    两个父类中的方法,属性,都会被子类继承
    class AAA():
        def methodAAA(self):
            print("a的方法a")
        # 新增方法,BBB类中有同名方法
        def methodBBB(self):
            print("a的方法b")
    class BBB():
        def methodBBB(self):
            print("b的方法b")
    class CCC(AAA,BBB):
        def methodCCC(self):
            self.methodAAA()
            self.methodBBB()
            print("c的方法c")
    ccc = CCC()
    ccc.methodCCC()
    # 执行结果
    # a的方法a
    # a的方法b
    # c的方法c
    

重写

重写父类的方法与调用父类的方法
  • 方法重写概念:

    所谓重写,就是在子类中,有一个和父类相同名字的方法,子类中的方法会覆盖掉父类中的同名方法
    
  • 方法重写案例:

    class SuperClass():
        def __init__(self):
            print("父类的初始化方法")
        def test(self):
            print("父类的测试方法")
    class SubClass(SuperClass):
        def __init__(self):
            print("子类的初始化方法")
        def test(self):
            print("子类的测试方法")
    sub = SubClass()
    # 这里的test方法,调用的为子类中重写的方法
    sub.test()
    # 执行结果
    # 子类的初始化方法
    # 子类的测试方法
    
  • 调用父类方法:

    class Cat(Animal,Active):
    	#1 super().__init__(name)
    	#2 Animal.__init__(self,name)
    
class SuperClass():
    def __init__(self,name):
        self.name = name
    def test(self):
        print("父类的测试方法")
class SubClass(SuperClass):
    def __init__(self,name,age):
       # SuperClass.__init__(self,name)
# super(SubClass, self).__init__(name)
super().__init__(name)
        self.age  = age
    # 子类重写父类方法
    def test(self):
        print("子类的测试方法")
        print('name:'+self.name+",age:"+str(self.age))

sub = SubClass('aa',12)
sub.test()
# 执行结果
# 子类的测试方法
# name:aa,age:12

多态

  • 概念

    • 定义时的类型跟运行时的类型不一样,此时就成为多态
      严格意义上来讲,python中的多态不叫真正的多态,称之为鸭子类型更合适
    • 鸭子类型
    “鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子,
    那它就可以被当做鸭子。也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。
    
    • 鸭子类型弊端
    “鸭子类型”语言的程序可能会在运行时因为不具备某种特定的方法而抛出异常:
    
    案例1:
    如果一只小狗(对象)想加入合唱团(以对象会不会嘎嘎嘎叫的方法为检验标准),
    也学鸭子那么嘎嘎嘎叫,好吧,它加入了,可是加入之后,却不会像鸭子那样走路,
    那么,迟早要出问题的。
    
    案例2:
    一只小老鼠被猫盯上了,情急之下,它学了狗叫,猫撤了之后,小老鼠的妈妈不无感叹的
    对它说:看吧,我让你学的这门儿外语多么重要啊。这虽然是个段子,但是,由于猫在
    思考时,使用了 "鸭子测试",它以为会叫的就是狗,会对自己产生威胁,所以撤退了,
    也正是因为这个错误的判断,它误失了一次进食机会。
    
  • 用法

class F1(object):
    def show(self):
        print("F1.show")
class S1(F1):
    def show(self):
        print("S1.show")
class S2(S1):
    def show(self):
        print("S2.show")
def func(obj):
    obj.show()

obj1 = F1()
func(obj1)
obj1 = S1()
func(obj1)
obj1 = S2()
func(obj1)

类属性、实例属性

类属性:class内,方法外

实例属性:方法内

  • 类属性
属于类对象所拥有的属性,它被所有类对象的实例对象所公有,在内存中只有一份
  • 类属性的访问方式

    • 在类外可以通过类名访问
    类名.属性名
    
    • 在类外可以通过实例对象访问
    对象名.属性名
    
  • 案例:

class Student:
    # 类属性
    schoolName="湖南"
    
    def __init__(self,name,age):
    
        # 实例属性
        self.name = name
        self.age = age
        
st1 = Student('陈独秀',29)
# 通过类名访问类属性
print(Student.schoolName)
# 通过对象访问类属性
print(st1.schoolName)
# 通过对象访问修改属性,会新增对象属性,之后通过对象访问类属性将无法访问到,因为会被新增的对象属性屏蔽
st1.schoolName = '京南校区'
# 类属性访问结果不变
print(Student.schoolName)
# 这只能访问到对象属性
print(st1.schoolName)
# 可以手动删除新增的对象属性
del st1.schoolName
# 因为对象属性被删除,所以,这访问的依旧是类属性
print(st1.schoolName)

静态方法和类方法

  • 类方法 @classmethod 实例属性+ @classmethod 变成类属性

    • 概念

    是类对象所拥有的方法,需要用 @classmethod 来表示,类方法第一个参数必须为类对象
    一般使用’cls’, 类方法能够通过类名和对象进行访问

    • 用法:
      class Student:

      类属性

      schoolName=“湖南”
      def init(self,name,age):
      # 实例属性
      self.name = name
      self.age = age

      类方法 (可以直接访问类属性,因此get方法中不能有self关键字,要用cls)

      @classmethod
      def getSchoolName(cls):
      return cls.schoolName

      @classmethod
      def setSchoolName(cls,newSchoolName):
      cls.schoolName = newSchoolName

    st2 = Student(‘李大钊’,30)
    Student.schoolName = ‘北平学校’

    通过对象访问类方法

    print(st2.getSchoolName())

    通过类名方法类方法(使用较多)

    print(Student.getSchoolName())
    Student.setSchoolName(‘同济学校’)
    print(Student.getSchoolName())
    注意: 类方法中可以直接修改当前类的类属性

  • 静态方法 @staticmethod

    • 概念
    需要使用 @staticmethod 进行修饰,静态方法不需要定义参数
    
    • 用法
    可以访问类属性,但是必须通过类名,
    调用方式:可以通过类名,对象进行调用
    class Student:
    
        # 类属性
        schoolName="湖南"
        def __init__(self,name,age):
            # 实例属性
            self.name = name
            self.age = age
            
        #   静态方法 (可以通过类名访问类属性)
        @staticmethod
        def getSchoolName():
            return Student.schoolName
    

Tips:

  • 成员属性、类属性、私有属性
  • 成员方法、类方法、静态方法、私有方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值