10、Python面向对象设计

目录

面向对象

自定义类

关键词class定义一个类

#!/usr/bin/env python
# encoding: utf-8

class Person:
    pass

self

Python中的self相当于this指针,指向自己,一个类可以实例化多个对象,当一个对象中的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,这时Python就知道调用哪个对象的方法了;假如一个方法没有self参数,那么就属于类方法,通过类来调用,但不能用类对象来调用,可以通过类.dict来查看类的内容

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.age = 24
    def skill(self):
        print("会做饭")

person = Person()
print(person.__dict__)#{'age': 24}
print(Person.__dict__)#{'__module__': '__main__', '__init__': <function Person.__init__ at 0x0000021BB95DFE18>,...

构造方法

init为构造方法,常在里面初始化一些成员变量,比如下面的name和age,他们的前面有self修饰,在实例化对象的时候自动会被调用

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        print("hello!")

其他一些方法

这里写图片描述

属性和方法

属性—成员变量,类中的变量,一般为区分都会带上self
方法—成员方法,类中的函数,第一个参数都为self

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zengraoli"
        self.age = 24

    def show_name(self):
        print("my name is:%s" % self.name)

实例化

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zengraoli"
        self.age = 24

    def show_name(self):
        print("my name is:%s" % self.name)

person = Person()
person.show_name()

公有和私有

默认上类所有的属性和方法都是公开的,可以通过.来获取,比如下面的

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zengraoli"
        self.age = 24

    def show_name(self):
        print("my name is:%s" % self.name)

person = Person()
person.show_name()
print(person.name)

还可以通过在属性和方法带上__两个下划线让其变成私有

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zengraoli"
        self.age = 24
        self.__addr = "addr"

    def show_name(self):
        print("my name is:%s" % self.name)
        print(self.__age())

    def __age(self):
        print("age")

person = Person()
person.show_name()
person.__age()#AttributeError: 'Person' object has no attribute '__age'
print(person.name)
print(person.__addr)#AttributeError: 'Person' object has no attribute '__addr'

静态方法

有时候我们可能需要用得到静态的方法
静态方法不会对任何成员变量进行修改,因此也不必传入self参数

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zengraoli"
        self.age = 24

    @staticmethod
    def show_info(name, age):
        print("name:%s, age:%d" % (name, age))

person = Person()
person.show_info(person.name, person.age)
Person.show_info(person.name, person.age)

类的一些其他特性

特性(property)、静态方法(staticmethod)、类方法(classmethod)、str的用法
请参考
https://www.cnblogs.com/wangyongsong/p/6750454.html#_label0


继承

简单的语法就能完成继承,比如下面的Parent和Child

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def show_info(self):
        print("Person.")

class Man(Person):
    def show_info(self):
        print("Man.")

person = Person()
person.show_info()#调用父类的方法

man = Man()
man.show_info()#调用子类的方法

有些情况下,需要在子类中调用父类的方法,比如从子类覆盖了父类的init方法,那么父类的变量就继承不了了,此时需要在子类的init方法中调用父类的init方法来解决

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zeng"
    def show_info(self):
        print("name:%s" % self.name)

class Man(Person):
    def __init__(self):
        self.age = "zeng"
    def show_info(self):
        print("name:%s, age:%s" %(self.name, self.age))

person = Person()
person.show_info()#name:zeng

man = Man()
man.show_info()#AttributeError: 'Man' object has no attribute 'name'

修改,应该在子类中调用父类的init方法才能找到这个name的变量,下面的两种方式均可以完成这个功能

调用父类方法

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zeng"
    def show_info(self):
        print("name:%s" % self.name)

class Man(Person):
    def __init__(self):#1、调用父类方法
        Person.__init__(self)
        self.age = "zeng"
    def show_info(self):
        print("name:%s, age:%s" %(self.name, self.age))

person = Person()
person.show_info()#name:zeng

man = Man()
man.show_info()#name:zeng, age:zeng

super函数

简单明了,也能完成调用父类方法的功能,当修改父类名称时,只需要修改继承类的名称

#!/usr/bin/env python
# encoding: utf-8

class Person(object):
    def __init__(self):
        self.name = "zeng"
    def show_info(self):
        print("name:%s" % self.name)

class Man(Person):
    def __init__(self): 
        super().__init__()#1、调用父类方法
        self.age = "zeng"
    def show_info(self):
        print("name:%s, age:%s" %(self.name, self.age))

person = Person()
person.show_info()#name:zeng

man = Man()
man.show_info()#name:zeng, age:zeng

多重继承

同时从多个类中继承,容易造成bug与理解困难,进来不要去使用它

#!/usr/bin/env python
# encoding: utf-8

class Mather(object):
    def __init__(self):
        self.x = 12
    def skill(self):
        print("会做饭")

class Farther(object):
    def __init__(self):
        self.x = 11
    def skill(self):
        print("会砍材")

class Child(Mather, Farther):
    pass

child = Child()
child.skill()#默认会调用第一个继承类的方法
print(child.x)#默认会使用第一个继承类的变量

相关的内置函数

issubclass(A, B)判断A是否是B的子类

#!/usr/bin/env python
# encoding: utf-8

class Farther(object):
    def __init__(self):
        self.x = 11
    def skill(self):
        print("会砍材")

class Child(Farther):
    pass

class Dog(object):
    pass

child = Child()
farther = Farther()
print(issubclass(Child, Farther))#True
print(issubclass(Dog, Farther))#False

isinstance(A,B)判断A是否是B的实例化对象

#!/usr/bin/env python
# encoding: utf-8

class Child(object):
    pass

child = Child()
print(isinstance(child, Child))#True

hasattr(object, attr_name)判断object类是否有attr_name属性

#!/usr/bin/env python
# encoding: utf-8

class Child(object):
    def __init__(self):
        self.name = 'zeng'

child = Child()
print(hasattr(child, 'name'))#True---注意属性需要带上引号
print(hasattr(child, 'age'))#False

getattr(object, attr_name, default_value)返回object中attr_name的值,不存在则返回default_value

返回对象指定的属性值,如果该属性不存在,则返回default;如果没有设置default返回ArttrbuteError

#!/usr/bin/env python
# encoding: utf-8

class Child(object):
    def __init__(self):
        self.name = 'zeng'

child = Child()
print(getattr(child, 'name'))#zeng
print(getattr(child, 'age', 25))#25---设置了default
print(getattr(child, 'age'))#AttributeError: 'Child' object has no attribute 'age'

setattr(object, attr_name, value)设置object中attr_name的值为value,如果存在这个属性值,则之前的值被覆盖

#!/usr/bin/env python
# encoding: utf-8

class Child(object):
    def __init__(self):
        self.name = 'zeng'

child = Child()
setattr(child, 'age', 25)#设置age的属性值为25
print(getattr(child, 'age'))#25

delattr(object, attr_name)删除object中attr_name的值

#!/usr/bin/env python
# encoding: utf-8

class Child(object):
    def __init__(self):
        self.name = 'zeng'

child = Child()
print(getattr(child, 'name'))#25
delattr(child, 'name')
print(getattr(child, 'name'))#AttributeError: 'Child' object has no attribute 'name'

property返回可以设置属性的属性,替代set、get和del

使用property的好处是,以后修改成员函数set、get和del名称时,都不需要改动其他代码(调用的时候只需要调用属性器的变量即可)

#!/usr/bin/env python
# encoding: utf-8

class Person:
    def __int__(self):
        self._name = 'zengraoli'
    def get_name(self):
        return self._name
    def set_name(self, value):
        self._name = value
    def del_name(self):
        del self._name

    # 设置属性器person_name_property,用person_name_property来替代get_name、set_name和del_name
    person_name_property = property(fget=get_name, fset=set_name, fdel=del_name)

person = Person()
person.person_name_property = 'zeng'
print(person.person_name_property)
print(person.get_name())

其实我们也可以自己写一个自己的property,比如这样的,也可以达到效果

#!/usr/bin/env python
# encoding: utf-8

class MyProperty:
    def __init__(self, fget=None, fset=None, fdel = None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    def __get__(self, instance, owner):
        return self.fget(instance)
    def __set__(self, instance, value):
        return self.fset(instance, value)
    def __delete__(self, instance):
        return self.fdel(instance)

class Person:
    def __int__(self):
        self._name = 'zengraoli'
    def get_name(self):
        return self._name
    def set_name(self, value):
        self._name = value
    def del_name(self):
        del self._name

    # 设置属性器person_name_property,用person_name_property来替代get_name、set_name和del_name
    person_name_property = MyProperty(fget=get_name, fset=set_name, fdel=del_name)

person = Person()
person.person_name_property = 'zeng'
print(person.person_name_property)
print(person.get_name())


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值