面向对象编程

面向对象基础


In [2]:
#在python中所有数据都是对象,每个对象都有自己的标识(表示在内存的地址),类型,和值,还有对应的方法
#使用dir可以查看某个变量的所有方法
s = "hello"
dir(s)


Out[2]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__getslice__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__len__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmod__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '_formatter_field_name_split',
 '_formatter_parser',
 'capitalize',
 'center',
 'count',
 'decode',
 'encode',
 'endswith',
 'expandtabs',
 'find',
 'format',
 'index',
 'isalnum',
 'isalpha',
 'isdigit',
 'islower',
 'isspace',
 'istitle',
 'isupper',
 'join',
 'ljust',
 'lower',
 'lstrip',
 'partition',
 'replace',
 'rfind',
 'rindex',
 'rjust',
 'rpartition',
 'rsplit',
 'rstrip',
 'split',
 'splitlines',
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

In [5]:
s.__len__()  #使用内置方法


Out[5]:
5

In [44]:
#定义一个对象
class People():
    'people 类'  #类说明,可以在__doc__中看到
    def __init__(self,name,age,height): #构造函数
        if type(name)!=type(""):     #类型检查,如果名字不是字符,则报错
            raise TypeError("name must be a srt")
        self.name = name
        self.age = age
        self.height = height
    def getInfo(self):
        print(self.name,self.age,self.height)
a = People("join",10,170)
print(a.name)

a.getInfo()  #调用对象中的方法

b = People(10,10,170) #名字不是字符则报错


join
('join', 10, 170)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-f017748cda60> in <module>()
     15 a.getInfo()  #调用对象中的方法
     16 
---> 17 b = People(10,10,170) #名字不是字符则报错

<ipython-input-44-f017748cda60> in __init__(self, name, age, height)
      4     def __init__(self,name,age,height): #构造函数
      5         if type(name)!=type(""):     #类型检查,如果名字不是字符,则报错
----> 6             raise TypeError("name must be a srt")
      7         self.name = name
      8         self.age = age

TypeError: name must be a srt

In [27]:
dir(a)   #我们之定义了两个方法,一个是__init__,另一个是getInfo,其余为python自定义方法


Out[27]:
['__doc__', '__init__', '__module__', 'age', 'getInfo', 'height', 'name']

In [46]:
print(a.__doc__)  
print(a.__module__)
print(a.__init__)


people 类
__main__
<bound method People.__init__ of <__main__.People instance at 0x000000000452A288>>

In [47]:
#私有变量,python中在变量名字前面加__则为私有变量,带_的变量默认为私有变量但是
#实际上是可以访问的,__something__为特殊变量,自己定义变量的时候不要用
class People():
    def __init__(self,name,age):
        self.__name = name
        self._age = age

a = People("join",10)
a._age              #可以访问,但是一般默认为私有,所以劲量遵守规则不要使用
#a.name #报错,可以发现编译器显示没有name的变量

a.name #私有变量,不可以访问


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-47-ad037f73a392> in <module>()
     10 #a.name #报错,可以发现编译器显示没有name的变量
     11 
---> 12 a.name

AttributeError: People instance has no attribute 'name'

In [51]:
#python实时上可以允许你干任意事情,尽管私有变量不可以访问,
#但是如果你是在想要访问也是可以的,但是一般默认还是不要使用
class People():
    def __init__(self,name,age):
        self.__name = name
        self._age = age

a = People("join",10)
print(a._People__name)  #可以通过这种方式访问,但是一般情况下不要使用


join

In [57]:
##对外公布私有变量接口,这要可以进行访问控制
class People():
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    def getName(self):
        return self.__name
    def setName(self,name): 
        if type(name) != type(" "):
            raise TypeError("wrong name")
        else:
            self.__name = name
a = People("join",10)
print(a.getName())
a.setName("jack")
print(a.getName())


join
jack

In [81]:
#python也支持类似JavaScript中的在对象外进行对象的操作
class People():
    pass
a = People()
a.name="join"   #在外部给对象添加一个属性
print(a.name)

a.__age=10
dir(a) #外部添加的加入了__之后的属性也可已进行访问
print(a.__age)

del a.__age        #删除属性
print(a.__age)

#尽管可以在外部进行定义,但是一般为了统一和便于阅读,还是尽量在内部进行类的定义


join
10
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-81-567bf0c005ba> in <module>()
     11 
     12 del a.__age        #删除属性
---> 13 print(a.__age)
     14 
     15 #尽管可以在外部进行定义,但是一般为了统一和便于阅读,还是尽量在内部进行类的定义

AttributeError: People instance has no attribute '__age'

继承和多态


In [83]:
#object是所有对象的父类
class People(object):   
    pass
a = People()
print(dir(a))   #可以看出People从object中继承了很多属性和方法


['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

In [92]:
#简单的继承
class People():
    def __init__(self):
        print("i am father __init__")
    def walk(self):
        print("i can walk")
class Man(People):
    pass

a = Man() #调用父类构造函数
a.walk()  #a继承了walk方法,也可以使用


i am father __init__
i can walk

In [95]:
#在子类中重写父类方法,一般先从自己的作用域中寻找变量以及函数,
#如果找不到则在父类中寻找,如果父类中还是找不到,则报错。
class People():
    def __init__(self):
        print("i am father __init__")
    def walk(self):
        print("i can walk")
class Man(People):
    def __init__(self):
        print("i am son __init__")
    def walk(self):
        print("i can jump")
a = Man()            #如果子类中有就使用子类中的构造方法
a.walk()


i am son __init__
i can jump

In [98]:
#python中也支持多继承
class People():
    def __init__(self):
        print("i am people")
class Run():
    def run(self):
        print("i can run")
class Man(People,Run):
    pass
a = Man()    #即是一个人,也会跑
a.run()


i am people
i can run

In [17]:
##python中的继承提倡利用父母,而不是从新复制父母
class People():
    def __init__(self,name,height,age):
        self.name = name
        self.height = height
        self.age = age
    def __str__(self):
        print(self.name)
class Tom(People):
    def __init__(self,height,age):              #在这个特殊子类中我们不想让使用者在此声明其名字
        People.__init__(self,"Tom",height,age)  #利用父类的构造函数

        
a = Tom(180,20)
a.__str__()


Tom

In [6]:
##面向对象中的一些工具
class Person():
    def __init__(self):
        self.name = ""
        self.age = ""
    pass
p = Person()
print(p.__class__)
print(p.__dict__)        ##以字典形式显示
print(p.__dict__.keys()) ##显示字典的键值


<class '__main__.Person'>
{'age': '', 'name': ''}
dict_keys(['age', 'name'])

In [6]:
##必须实现的方法
class People():
    def __init__(self,name):
        self.name = name
    def makeFood(self,materials):
        assert False,"must be define"
class Join(People):
    def __init__(self,name):
        People.__init__(self,name)
    def makeFood(self,materials):
        print("food")
a = Join("a")
a.makeFood("water")


food

运算符重载


In [46]:
class Number():
    def __init__(self,value):
        self.data = value
    def __str__(self):
        print(self.data)
class sonNumber(Number):
    def __add__(self,other):
        if isinstance(other,sonNumber):
            return sonNumber(self.data+other.data)
        else:
            return sonNumber(self.data+other)
    def __sub__(self,other):
        return sonNumber(self.data-other)
    def __radd__(self,other):
        return sonNumber(other+self.data)
    def __iadd__(self,other):
        self.data+=other
        return self
#加数值
a = sonNumber(10)
c = a+3
c.__str__()


#加数值
a = sonNumber(10)
c = 3+a
c.__str__()

# +=运算
a = sonNumber(10)
a+=1
a.__str__()


#加变量
a = sonNumber(10)
b = sonNumber(20)
c = a+b
c.__str__()

#减
a = sonNumber(10)
c = a-3
c.__str__()

print(isinstance(a,sonNumber))


13
13
11
30
7
True

In [43]:
##索引和分片
class myList:
    def __init__(self,li):
        self.li = li
    def __getitem__(self,index):
        return self.li[index]
a = [1,2,3,4]
ml = myList(a)
print(ml[1])  #索引
print(ml[:])  #分片
print(ml[::-1])


2
[1, 2, 3, 4]
[4, 3, 2, 1]

In [34]:
##属性拦截
class Value:
    def __getattr__(self,attrname):
        if attrname == "value":
            self.value = 10
        else:
            print("wrong")
a = Value()
a.value

In [41]:
##字符输出
class pr:
    def __init__(self,value):
        self.value = value
    def __repr__(self):
        return str(self.value)
    def __str__(self):
        return "str"
a = pr(10)
repr(a),str(a)


Out[41]:
('10', 'str')

In [50]:
##比较大小
class Value:
    def __init__(self,value):
        self.value = value
    def __gt__(self,other):
        return self.value>other
    def __lt__(self,other):
        return self.value<other
a = Value(10)
print(a>20)
print(a<11)


False
True

In [55]:
class myList:
    def __init__(self,value):
        self.value = value
    def __bool__(self):
        return True
    def __len__(self):
        return len(self.value)
    
a = myList([1,2,3,-1])
bool(a),len(a)


Out[55]:
(True, 4)

In [62]:
#析构函数,类似于c++中的析构函数,在对象销毁时自动调用,一般在python中不用因为python会自动回收其对象
class Person:
    def __del__(self):
        print("bye")
a = Person()
a = 10   #对象指向其他地址,此时销毁对象Person,调用析构函数


bye

对象序列化

  • pickle
  • dbm
  • shelve

这个将在LibsInPython文件夹中更新


In [5]:



---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-5-eddad4fdca0a> in <module>()
----> 1 assert False, "sadf"

AssertionError: sadf

In [ ]: