学学python2(面向对象OOP)

2018-12-17  本文已影响0人  鱼丸_a47d

面向对象:

oop

类与对象

类的基本实现

类的命名

声明一个类

访问对象成员

obj.成员属性/成员方法

#定义一个的类
class student():
    #一个空类,pas代表直接跳过
    #此处pass必须有
    psss
#定义一个对象
mingyue= student()
# 在定义一个类,用来描述听Python的学生
class PythonStudent():
    # 用None给不确定的值赋值
    name = None
    age = 18
    course = "Python"
    # 需要注意
    # 1. def doHomework的缩进层级
    # 2. 系统默认由一个self参数
    def doHomework(self):
        print("I 在做作业")
        # 推荐在函数末尾使用return语句
        return None
# 实例化一个叫yueyue的学生,是一个具体的人
yueyue = PythonStudent()
print(yueyue.name)
print(yueyue.age)
# 注意成员函数的调用没有传递进入参数
yueyue.doHomework()

类与对象的成员分析

class A():
    name = "dana"
    age = 18    
    # 注意say的写法,参数由一个self
    def say(self):
        self.name = "aaaa"
        self.age = 200
# 此案例说明
# 类实例的属性和其对象的实例的属性在不对对象的实例属性赋值的前提下,
# 指向同一个变量  
# 此时,A称为类实例
print(A.name)
print(A.age)
print("*" * 20)
# id可以鉴别一个变量是否和另一个变量是同一变量
print(id(A.name))
print(id(A.age))
print("*" * 20)
a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
-----------

dana
18
********************
140666260313176
93936169025280
********************
dana
18
140666260313176
93936169025280
------------------
print(A.name)
print(A.age)

print("*" * 20)

# id可以鉴别一个变量是否和另一个变量是同一变量
print(id(A.name))
print(id(A.age))

print("*" * 20)
a = A()
# 查看A内所有的属性
print(A.__dict__)
print(a.__dict__)

a.name = "yaona"
a.age = 16
print(a.__dict__)

print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
-------------------
dana
18
********************
140666260313176
93936169025280
********************
{'__module__': '__main__', 'name': 'dana', 'age': 18, 'say': <function A.say at 0x7fef6a799730>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{}
{'name': 'yaona', 'age': 16}
yaona
16
140666251554240
93936169025216

Self

class Student():
    name = "dana"
    age = 18
    
    # 注意say的写法,参数由一个self
    def say(self):
        self.name = "aaaa"
        self.age = 200
        print("My name is {0}".format(self.name))
        print("My age is {0}".format(self.age))
        
    def sayAgain(s):
#self并不是关键字,只是一个用于接受对象的普通参数,理论上可以用任何一个普通变量名代替      
        print("My name is {0}".format(s.name))
        print("My age is {0}".format(s.age))
          
yueyue = Student()
yueyue.say()
yueyue.sayAgain()
-----------------------
My name is aaaa
My age is 200
My name is aaaa
My age is 200
class Teacher():
    name = "dana"
    age = 19
    
    def say(self):
        self.name = "yaona"
        self.age = 17
        print("My name is {0}".format(self.name))
        # 调用类的成员变量需要用 __class__
        print("My age is {0}".format(__class__.age))
    def sayAgain():
        print(__class__.name)
        print(__class__.age )
        print("Hello, nice to see you again")
        
t = Teacher()
t.say()
# 调用绑定类函数使用类名
Teacher.sayAgain()
---------------------
My name is yaona
My age is 19
dana
19
Hello, nice to see you again
class A():
    name = " liuying"
    age = 18
    
    def __init__(self):
        self.name = "aaaa"
        self.age = 200
        
    def say(self):
        print(self.name)
        print(self.age)
        
class B():
    name = "bbbb"
    age = 90
    
a = A()
# 此时,系统会默认把a作为第一个参数传入函数
a.say()
   
# 此时,self被a替换
A.say(a)
# 同样可以把A作为参数传入
A.say(A)

# 此时,传入的是类实例B,因为B具有name和age属性,所以不会报错
A.say(B)

# 以上代码,利用了鸭子模型
-----------------------
aaaa
200
aaaa
200
 liuying
18
bbbb
90

面向对象的三大特征

封装

- 封装就是对对象成员进行访问限制
class Person():
                # name是共有的成员 
                name = "liuying"
                # __age就是私有成员
                __age = 18
                
p = Person()
# name是公有变量
print(p.name)
# __age是私有变量
print(p.__age)
-----------------
liuying
19
----------------
# name mangling技术
print(Person.__dict__)

p._Person__age = 19
print(p._Person__age)

{'__module__': '__main__', 'name': 'liuying', '_Person__age': 18, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
19

继承


class Person:
    name ="noname"
    age=18
    __score=0
    _petname="sec"
    def sleep(self):
        print("sleeping")
class Teacher(Person):
    teacher_id=34
    def make_test(self):
        print("attention")
t=Teacher()
print(t.name)
print(t._petname)
# print(t.__score)
t.sleep()
print(t.teacher_id)
t.make_test()
------------
noname
sec
sleeping
34
attention
class Person():
    name = "NoName"
    age = 18
    __score = 0 # 考试成绩是秘密,只要自己知道
    _petname = "sec" #小名,是保护的,子类可以用,但不能公用
    def sleep(self):
        print("Sleeping ... ...")
 
        
#父类写在括号内
class Teacher(Person):
    teacher_id = "9527"
    name = "DaNa"
    def make_test(self):
        print("attention")
        
t = Teacher()
print(t.name)
---------------
DaNa
#人由工作的函数, 老师也由工作的函数,但老师的工作需要讲课
class Person():
    name = "NoName"
    age = 18
    __score = 0 # 考试成绩是秘密,只要自己知道
    _petname = "sec" #小名,是保护的,子类可以用,但不能公用
    def sleep(self):
        print("Sleeping ... ...")
    def work(self):
        print("make some money")
class Teacher(Person):
    teacher_id = "9527"
    name = "DaNa"
    def make_test(self):
        print("attention")
    def work(self):
        Person.work(self)
        #super().work()
        self.make_test()
t=Teacher()
t.work()
---------
make some money
attention
class Dog():
    # __init__就是构造函数
    # 每次实例化的时候,第一个被自动的调用
    # 因为主要工作是进行初始化,所以得名
    def __init__(self):
        print("I am init in dog")
# 实例话的时候,括号内的参数需要跟构造函数参数匹配
kaka = Dog()
----------------
I  am init in dog
class Animel():
    def __init__(self):
        print("Animel")

class PaxingAni(Animel):
    def __init__(self):
        print(" Paxing Dongwu")

class Dog(PaxingAni):
    # __init__就是构造函数
    # 每次实例化的时候,第一个被自动的调用
    # 因为主要工作是进行初始化,所以得名
    def __init__(self):
        print("I am init in dog")
        
# 实例话的时候,自动调用了Dog的构造函数
# 因为找到了构造函数,则不在查找父类的构造函数
kaka = Dog()

# 猫没有写构造函数
class Cat(PaxingAni):
    pass

# 此时应该自动调用构造函数,因为Cat没有构造函数,所以查找父类构造函数
# 在PaxingAni中查找到了构造函数,则停止向上查找
c = Cat()
-----------------
I am init in dog
 Paxing Dongwu
class Animel():
    def __init__(self):
        print("Animel")

class PaxingAni(Animel):
    def __init__(self, name):
        print(" Paxing Dongwu {0}".format(name))

class Dog(PaxingAni):
    # __init__就是构造函数
    # 每次实例化的时候,第一个被自动的调用
    # 因为主要工作是进行初始化,所以得名
    def __init__(self):
        print("I am init in dog")
        
# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错      
d = Dog()

class Cat(PaxingAni):
    pass

# 此时,由于Cat没有构造函数,则向上查找
#  因为PaxingAni的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()

I am init in dog

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-160de1fa11e4> in <module>()
# 此时,由于Cat没有构造函数,则向上查找
#  因为PaxingAni的构造函数需要两个参数,实例化的时候给了一个,报错
 c = Cat()
-------------
I am init in dog
TypeError: __init__() missing 1 required positional argument: 'name'
class Animel():
    def __init__(self):
        print("Animel")

class PaxingAni(Animel):
    pass

class Dog(PaxingAni):
    pass
        
# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错      
d = Dog()

class Cat(PaxingAni):
    pass

# 此时,由于Cat没有构造函数,则向上查找
#  因为PaxingAni的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()
------------------
Animel
Animel
class A():
    pass
class B():
    pass
print(A.__mro__)
print(B.__mro__)
--------------
(<class '__main__.A'>, <class 'object'>)
(<class '__main__.B'>, <class 'object'>)
# 子类可以直接拥有父类的属性和方法,私有属性和方法除外
class Fish():
    def __init__(self,name):
        self.name = name
    def swim(self):
        print("i am swimming......")
        
class Bird():
    def __init__(self, name):
        self.name = name
        
    def fly(self):
        print("I am flying.....")

class Person():
    def __init__(self, name):
        self.name = name
        
    def work(self):
        print("Working........")
        
        

        
# 单继承的例子      
class Student(Person):
    def __init__(self, name):
        self.name = name
stu = Student("yueyue")
stu.work()
        
        
# 多继承的例子  
class SuperMan(Person, Bird, Fish):
    def __init__(self, name):
        self.name = name


class SwimMan(Person, Fish):
    def __init__(self, name):
        self.name = name
        
s = SuperMan("yueyue")
s.fly()
s.swim()
--------------------
Working........
I am flying.....
i am swimming......

菱形继承/钻石继承问题

class A():
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        print("B")
        
class C(B):
    pass
c = C()
--------
B
# 构造函数的调用顺序 - 1

# 构造函数的调用顺序 - 1
# 如果子类没有写构造函数,则自动向上查找,知道找到位置
class A():
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        print("B")
        
class C(B):
    pass

# 此时,首先查找C的构造函数
# 如果没有,则向上按照MRO顺序查找父类的构造函数,知道找到为止
c = C()
-----------------
B
---------------------
# 构造函数的调用顺序 - 2
class A():
    def __init__(self):
        print("A")

class B(A):
    def __init__(self, name):
        print("B")
        print(name)
        
class C(B):
    pass
c = C()
----------------
TypeError: __init__() missing 1 required positional argument: 'name'
-----------
# 构造函数的调用顺序 - 3
class A():
    def __init__(self):
        print("A")

class B(A):
    def __init__(self, name):
        print("B")
        print(name)
        
class C(B):
    # c中想扩展B的构造函数,
    # 即调用B的构造函数后在添加一些功能
    # 由两种方法实现
    
    '''
    # 第一种是通过父类名调用
    def __init__(self, name):
        # 首先调用父类构造函数
        B.__init__(self, name)
        # 其次,再增加自己的功能
        print("这是C中附加的功能")
    '''  
        
    # 第二种,使用super调用
    def __init__(self, name):
        # 首先调用父类构造函数
        super(C, self).__init__(name)
        # 其次,再增加自己的功能
        print("这是C中附加的功能")
        

# 此时,首先查找C的构造函数
# 如果没有,则向上按照MRO顺序查找父类的构造函数,知道找到为止
# 此时,会出现参数结构不对应错误
c = C("我是C")
--------------------
B
我是C
这是C中附加的功能
------------

多态

class Person():
                name = "liuying"
                age = 18

                def eat(self):
                    print("EAT.......")
                    
                def drink(self):
                    print("DRINK......")
                    
                def sleep(self):
                    print("SLEEP.....")
                
class Teacher(Person):
                def work(self):
                    print("Work")

class Student(Person):
                def study(self):
                    print("Study")
                    

class Tutor(Teacher, Student):
                pass

t = Tutor()
             
print(Tutor.__mro__)
print(t.__dict__)
print(Tutor.__dict__)

print("*"*20)
class TeacherMixin():
                def work(self):
                    print("Work")

class StudentMixin():
                def study(self):
                    print("Study")
                    
class TutorM(Person, TeacherMixin, StudentMixin):
                pass
tt = TutorM()
print(TutorM.__mro__)
print(tt.__dict__)
print(TutorM.__dict__)
———————
(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
********************
(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.Studen
class A():
    pass

class B(A):
    pass

class C():
    pass

print( issubclass(B, A))
print( issubclass(C, A))
print( issubclass(B, object))
—————-
True
False
True
——————
# isinstance
class A():
    pass

a = A()

print(isinstance(a, A))
print(isinstance(A, A))
——————
True
False
————-
# hasattr
class A():
    name = "NoName"
    
a = A()
print(hasattr(a, "name" ))
print(hasattr(a, "age" ))
——————
True
False

类的相关函数

类的成员描述符(属性)

class Student():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
        # 如果不想修改代码
        self.setName(name)
        
    # 介绍下自己
    def intro(self):
        print("Hai, my name is {0}".format(self.name))
        
    def setName(self, name):
        self.name = name.upper()
        
s1 = Student("LIU Ying", 19.8)
s2 = Student("michi stangle", 24.0)

s1.intro()
s2.intro()
-----------------------------
Hai, my name is LIU YING
Hai, my name is MICHI STANGLE

property(fget, fset, fdel, doc)

# peroperty案例
# 定义一个Person类,具有name,age属性
# 对于任意输入的姓名,我们希望都用大写方式保存
# 年龄,我们希望内部统一用整数保存
# x = property(fget, fset, fdel, doc)
class Person():
    '''
    这是一个人,一个高尚的人,一个脱离了低级趣味的人
    他还他妈的有属性
    '''
    # 函数的名称可以任意
    def fget(self):
        return self._name * 2
    
    def fset(self, name):
        # 所有输入的姓名以大写形式保存
        self._name = name.upper()
        
    def fdel(self):
        self._name = "NoName"
    
    name = property(fget, fset, fdel, "对name进行下下操作啦")
p1 = Person()
p1.name = "TuLing"
print(p1.name)
----------------
TULINGTULING

类的内置属性

dict:以字典的方式显示类的成员组成
doc: 获取类的文档信息
name:获取类的名称,如果在模块中使用,获取模块的名称
bases: 获取某个类的所有父类,以元组的方式显示

类的魔方函数

就是

上一篇下一篇

猜你喜欢

热点阅读