python面向对象

1. 构造方法

def __init__(self):
    pass

构造方法,可以理解为初始化方法,构造函数。主要功能:

(1)初始化一个类的属性

(2)当新成员被创建的时候,会自动调用。

class People:
    def __init__(self):
        print('hello world')

p = People()

class People:
    def __init__(self, name, age):
        print(name, ':', age)


p = People('小明', '20')

self

(1) self代表类的实例,而非类。

self代表的是类的实例。而self.__class__则指向类。

(2) self可以写成this

还是尊重常见的习惯,建议使用self

class People:
    def __init__(this):
        print('hello world')

p = People()

(3)方法第一个参数,必须为self,self代表的是类的实例

为什么一定要写self呢?

可以简单理解为:函数被实例调用的时候,它总得知道谁在调用吧。

class People:
    def __init__(self, name, age):
        # 通过下面和实例绑定
        self.name = name
        self.age = age
        print(name, ':', age)

    def eat(self):
        print(self.name,'吃什么')

p = People('小明', '20')
p.eat()

扫一扫欢迎关注【 python王哪去 】,一起学习!python面向对象_第1张图片

2. 类属性与实例属性

类属性:公共属性,所有实例共享

实例属性:成员变量,每个实例独享

class People:
    p_nation = '中国'
    def __init__(self, name, age):
        # 通过下面和实例绑定
        self.name = name
        self.age = age
        print(name, ':', age)

p = People('小明', '20')


print(People.p_nation)
print(p.p_nation)

实例重新定义公共属性,其实是增加自己成员变量

class People:
    p_nation = '中国'
    def __init__(self, name, age):
        # 通过下面和实例绑定
        self.name = name
        self.age = age
        print(name, ':', age)

p = People('小明', '20')

p.p_nation ='美国'
print(p.p_nation) # 美国
print(People.p_nation) # 中国

3. 类的继承

继承是指将现有类的属性和行为,经过修改或重写之后,就可产生出拥有新功能的类,这样可以大幅提升程序代码的可重用性。更大的优势在于能够维持对象封装的特性。

在概念上来说:父类被称为基类,子类被称为派生类。

单继承

class Father:
    name ='Father'
    def work(self):
        print("在家种地")

class Son(Father):

   def __init__(self):
       pass

son = Son()
son.work()
# 在家种地
print(son.name)
# Father

重写父类方法 和 变量

class Father:
    name ='Father'
    def work(self):
        print("在家种地")

class Son(Father):

    name = 'Son'

    def work(self):
        print("在上学")

son = Son()
son.work()
# 在上学
print(son.name)
# Son

除了调用原来父类的方法,还根据自己的需求扩展了子类的方法。

class Father:
    def work(self):
        print("在家种地")

class Son(Father):
    def work(self):
        Father.work(self)
        print("在上学")


son = Son()
son.work()

所以,super() 函数调用父类

class Father:
    name = 'Father'

    def work(self,content):
        print("在家种地,",content)


class Son(Father):
    name = 'son'

    def work(self,content):
        super().work(content)
        print("在上学,学习",content)


f = Father()
f.work('花生')
s = Son()
s.work('语文')


# 在家种地, 花生
# 在家种地, 语文
# 在上学,学习 语文

4. 多继承

多继承是指派生类继承自多个基类,而这些被继承的基类相互之间可能都没有关系,简单地说,就是直接继承了两个或两个以上的基类。

class Animal:
    def content(self):
        print('它们都是动物')

class Horse(Animal):
    def content1(self):
        print('它是马')


class Donkey(Animal):

    def content2(self):
        print('它是驴')

class Mule(Horse, Donkey):
    def content3(self):
        print('它是骡子')

m = Mule()
m.content()
m.content1()
m.content2()
m.content3()

print(isinstance(m,Animal))
print(issubclass(Mule,Animal))
print(issubclass(Mule,Horse))
print(issubclass(Horse,Donkey))


它们都是动物
它是马
它是驴
它是骡子

True
True
True
False

相关函数

isinstance( 对象, 类)

判断第一个参数的对象是否属于第二个参数类的一种

issubclass(子类,父类)

如果类 1 是类 2 所指定的子类,则返回 True,否则返回 False

5. 封装

将数据和操作数据的方法 包装在一起 , 隐藏数据的内部细节 , 防止外界的直接访问和修改 。

封装后 , 只能通过 对外提供的接口 , 对 封装在内部的属性和方法 进行 访问和操作
 

成员变量 与 成员方法

class People:
    p_nation = '中国'

    def eat(self):
        print(self.p_nation)

私有成员变量 与 私有成员方法

私有成员变量 : 以 双下划线 开头 __私有成员变量名

私有成员方法 : 以 双下划线 开头 __私有成员方法名

class People:
    __name = '小明'

    def say(self):
        # 只能在内部掉用
        self.__name = '大明'
        self.__say() 
        print(self.__name)

    def __say(self):
        self.__name = '__大明'
        print('say chinese')


p = People()
p.say()

###########

say chinese
__大明

6. 多态

Python是弱类型语言,其最明显的特征是在使用变量时,无需为其指定具体的数据类型。这会导致一种情况,即同一变量可能会被先后赋值不同的类对象。

类的多态特性,还要满足以下 2 个前提条件:

(1)继承:多态一定是发生在子类和父类之间;

(2)重写:子类重写了父类的方法。

class People:
    def hello(self):
        print('hello people')

class Men(People):
    def hello(self):
        print('hello man')

class Women(People):
    def hello(self):
        print('hello woman')

class Test:
    def hello(self, arg):
        arg.hello()

p = People()
men = Men()
women = Women()
test = Test()
test.hello(p)
test.hello(men)
test.hello(women)

#######
hello people
hello man
hello woman

7. 类的一些方法

类的实例方法:在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数。

类的实例私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods 。

class People:
    name = '小明'
    __name = '__小明'

    def say(self):
        # 只能在内部掉用
        self.__name = '大明'
        self.__say() 
        print(self.__name)

    def __say(self):
        self.__name = '__大明'
        print('say chinese')

p = People()
p.say()

###########

say chinese
__大明

类的方法: 无需实例化,可以通过类直接调用的方法,但是方法的第一个参数接收的一定是类本身。

使用类方法不需要定义一个实例,类方法中的cls指向类,不像实例方法中的self指向一个实例。定义类方法,需要在函数前添加@classmethod

class People:
    __name = '小明'

    @classmethod
    def hello(cls):
        print(cls.__name)



People.hello()

静态方法

一般用于和类对象以及实例对象无关的代码。也就是意思不能访问类变量,也不能访问实例变量。

class People:

    @staticmethod
    def hello_word():
        print('hello world')


People.hello_word()

属性方法(@property)

使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。

加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。


class People:

    @property
    def hello_1(self):
        return 'hello'

	@property
    def hello_2(self):
        return self.__name


p = People()
print(p.hello_1)
print(p.hello_2)

户进行属性调用的时候,直接调用hello_2即可,而不用知道属性名_name,因此用户无法更改属性,从而保护了类的属性。

8. 反射

python的反射机制,核心就是利用字符串去已存在的模块中找到指定的属性或方法,找到方法后自动执行(基于字符串的事件驱动)。

一般使用场景:动态的向对象中添加属性和方法;也可以动态的调用对象中的方法或者属性。

hasattr(obj,name_str)

判断输入的name_str字符串在对象obj中是否存在(属性或方法),存在返回True,否则返回False。

class People():
    nation = 'CN'

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def get_name(self):
        print(self.name)


p = People('小明',18)
print(hasattr(People, 'nation'))
print(hasattr(p, 'age'))
print(hasattr(People, 'get_name'))
print(hasattr(People, 'xxxxxx'))



True
True
True
False

getattr(obj,name_str)

将按照输入的name_str字符串在对象obj中查找,如找到同名属性,则返回该属性;如找到同名方法,则返回方法的引用;如果未能找到同名的属性或者方法。

class People():
    nation = 'CN'

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def get_name(self):
        print(self.name)


p = People('小明',18)

# 反射获取类变量
print(getattr(People, 'nation'))
# 反射获取成员变量
print(getattr(p, 'name'))
# 反射获取成员方法,返回方法是一个引用地址,要想执行该方法,需要在后面加上小括号
getattr(p, 'get_name')()


#########
CN
小明
小明

setattr(obj,name_str,value)

name_str为属性名或者方法名,value为属性值或者方法的引用。

class People():
    nation = 'CN'

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def get_name(self):
        print(self.name)


p = People('小明',18)

setattr(p, 'name','小小明')
print(getattr(p,'name'))
setattr(p,'new_get_name',p.get_name)
getattr(p, 'new_get_name')()

##################

小小明
小小明

delattr(obj,name_str)

将你输入的字符串name_str在对象obj中查找,如找到同名属性或者方法就进行删除。

删除属性和方法之后,再次调用就会报AttributeError错误

class People():
    nation = 'CN'

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def get_name(self):
        print(self.name)


p = People('小明',18)


delattr(p,'name')
getattr(p,'name')
delattr(p,'new_get_name')
getattr(p, 'new_get_name')()


#######

AttributeError: 'People' object has no attribute 'name'

你可能感兴趣的:(Python,python,开发语言,面向对象)