zoukankan      html  css  js  c++  java
  • 面向对象编程进阶

    1、   静态方法staticmethod

    只是名义上归类管理,实际上再静态方法里访问不了类和实例中的任何属性

    定义:

    通过@staticmethod装饰器即可以把其装饰的方法变为一个静态方法,普通的方法可以在实例化之后直接调用,并且在方法里可以通过self调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量。

    如果按照之前学习的面向对象,写一个简单的代码如下:

    1 class Dog(object):    
    2 def __init__(self,name):
    3         self.name = name
    4 
    5     def eat(self,food):
    6         print("%s is eating %s" %(self.name,food))
    7 
    8 d =Dog("小A")
    9 d.eat("包子")

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法1.py
    2 小A is eating 包子
    3 
    4 Process finished with exit code 0

    接着对代码进行修改

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     @staticmethod  
     6     def eat(self,food):
     7         print("%s is eating %s" %(self.name,food))
     8 
     9 
    10 d = Dog("小A")
    11 d.eat("包子")

    运行结果:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 Traceback (most recent call last):
    3   File "D:/python培训/s14/day7/静态方法.py", line 14, in <module>
    4     d.eat("包子")
    5 TypeError: eat() missing 1 required positional argument: 'food'
    6 
    7 Process finished with exit code 1

    出现了如上述的错误,为了避免food参数的问题,我们再次将代码进行修改:

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     @staticmethod
     6     def eat(self):
     7         print("%s is eating %s" %(self.name,"包子"))
     8 
     9 
    10 d = Dog("小A")
    11 d.eat()

    但是运行结果仍然出现如下错误:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 Traceback (most recent call last):
    3   File "D:/python培训/s14/day7/静态方法.py", line 14, in <module>
    4     d.eat()
    5 TypeError: eat() missing 1 required positional argument: 'self'
    6 
    7 Process finished with exit code 1

    其实这就是静态方法,这个时候eat函数和类其实没有上面关系,也可以说静态方法阶段了函数和类的关系

    我们再次将代码进行更改:

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     @staticmethod
     6     def eat():
     7         print("%s is eating %s" %("小A","包子"))
     8 
     9 
    10 d = Dog("小A")
    11 d.eat()

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 小A is eating 包子
    3 
    4 Process finished with exit code 0

    如果非要传入参数可以将代码更改为,但是下面的代码意义不是特别大:

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     @staticmethod
     6     def eat(self):
     7         print("%s is eating %s" %(self.name,"包子"))
     8 
     9 
    10 d = Dog("小A")
    11 d.eat(d)

    运行结果也是正常的

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 小A is eating 包子
    3 
    4 Process finished with exit code 0

    2、  类方法classmethod

    类方法只能访问类变量,不能访问实例变量

    我们先写如下代码

    1 #AUTHOR:FAN
    2 class Dog(object):
    3     def __init__(self,name):
    4         self.name = name
    5     @classmethod
    6     def eat(self):
    7         print("%s is eating %s" %(self.name,"包子"))
    8 d = Dog("dean")
    9 d.eat()

    运行结果出现如下错误:

    1 D:python35python.exe D:/python培训/s14/day7/类方法2.py
    2 Traceback (most recent call last):
    3   File "D:/python培训/s14/day7/类方法2.py", line 15, in <module>
    4     d.eat()
    5   File "D:/python培训/s14/day7/类方法2.py", line 7, in eat
    6     print("%s is eating %s" %(self.name,"包子"))
    7 AttributeError: type object 'Dog' has no attribute 'name'
    8 
    9 Process finished with exit code 1

    上述显示无法调用到name

    将代码进行修改

    1 class Dog(object):
    2     name = "AAA"
    3     def __init__(self,name):
    4         self.name = name
    5     @classmethod
    6     def eat(self):
    7         print("%s is eating %s" %(self.name,"包子"))
    8 d = Dog("dean")
    9 d.eat()

    运行效果如下:

    1 D:python35python.exe D:/python培训/s14/day7/类方法2.py
    2 AAA is eating 包子
    3 
    4 Process finished with exit code 0

    从上面的运行结果可以看出虽然我实例化的时候传入了dean但是确实类变量AAA

    3、属性方法property

    将一个方法变成一个静态属性

    我们先写如下代码:

    1 class Dog(object):
    2     def __init__(self,name):
    3         self.name = name
    4     @property
    5     def eat(self):
    6         print("%s is eating %s" %(self.name,"包子"))
    7 d = Dog("dean")
    8 d.eat()

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/属性方法2.py
    2 dean is eating 包子
    3 Traceback (most recent call last):
    4   File "D:/python培训/s14/day7/属性方法2.py", line 9, in <module>
    5     d.eat()
    6 TypeError: 'NoneType' object is not callable
    7 
    8 Process finished with exit code 1

    所以我将代码进行修改(将d.eat()改为d.eat):

    1 #AUTHOR:FAN
    2 class Dog(object):
    3     def __init__(self,name):
    4         self.name = name
    5     @property
    6     def eat(self):
    7         print("%s is eating %s" %(self.name,"包子"))
    8 d = Dog("dean")
    9 d.eat

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/属性方法2.py
    2 dean is eating 包子
    3 
    4 Process finished with exit code 0

    从上面可以看出将一个方法变成一个静态属性

    但是这个时候也同样发现无法传参数了。并且及时是已经是一个静态属性了,也是不能赋值的

    如果想要赋值,可以将代码进行如下修改:

     1 class Dog(object):
     2     def __init__(self,name):
     3         self.name = name
     4         self.__food = None
     5     @property
     6     def eat(self):
     7         print("%s is eating %s" %(self.name,self.__food))
     8     @eat.setter
     9     def eat(self,food):
    10         print("set to food:",food)
    11         self.__food = "包子"
    12 d = Dog("dean")
    13 d.eat
    14 d.eat="包子"
      d.eat

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/属性方法2.py
    2 dean is eating None
    3 set to food: 包子
    4 dean is eating 包子
    5 
    6 Process finished with exit code 0

    这样通过上面的方法就可以对其作为属性进行赋值修改

    但是默认情况下属性方法是无法删除的,如果想要删除,需要:

     1 #AUTHOR:FAN
     2 class Dog(object):
     3     def __init__(self,name):
     4         self.name = name
     5         self.__food = None
     6     @property
     7     def eat(self):
     8         print("%s is eating %s" %(self.name,self.__food))
     9     @eat.setter
    10     def eat(self,food):
    11         print("set to food:",food)
    12         self.__food = "包子"
    13     @eat.deleter
    14     def eat(self):
    15         del self.__food
    16         print("删完了")
    17 
    18 d = Dog("dean")
    19 d.eat
    20 d.eat="包子"
    21 d.eat
    22 del d.eat

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/属性方法2.py
    2 dean is eating None
    3 set to food: 包子
    4 dean is eating 包子
    5 删完了
    6 
    7 Process finished with exit code 0

    4、 类的特殊成员方法

    __doc__表示类的描述信息

    __module__表示当前操作的对象在哪个模块

    __class__表示当前操作的对象的类是什么

    __init__构造方法,通过类创建对象时,自动触发执行

    __del__ 析构函数,当对象在内存中释放时,自动触发执行

    __call__对象后面加括号,触发执行

    代码例子:

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     # @staticmethod
     6     def eat(self,food):
     7         print("%s is eating %s" %(self.name,food))
     8     def __call__(self, *args, **kwargs):
     9         print("running call",args,kwargs)
    10 
    11 
    12 d = Dog("小A")
    13 d(1,2,3,4,name="dean")

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 running call (1, 2, 3, 4) {'name': 'dean'}
    3 
    4 Process finished with exit code 0

    __dict__查看类或对象中的所有成员

    代码例子:

     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5     # @staticmethod
     6     def eat(self,food):
     7         print("%s is eating %s" %(self.name,food))
     8     def __call__(self, *args, **kwargs):
     9         print("running call",args,kwargs)
    10 
    11 
    12 d = Dog("小A")
    13 # d(1,2,3,4,name="dean")
    14 print(Dog.__dict__)
    15 print(d.__dict__)

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/静态方法.py
    2 {'__doc__': None, 'eat': <function Dog.eat at 0x0000000000B6E378>, '__init__': <function Dog.__init__ at 0x0000000000B6E2F0>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__call__': <function Dog.__call__ at 0x0000000000B6E400>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__module__': '__main__'}
    3 {'name': '小A'}
    4 Process finished with exit code 0

    从上面例子也可以看出print(Dog.__dict__)打印类里的所有属性,不包括实例属性

    print(d.__dict__)打印所有实例属性,不包括类属性

    __str__如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值

    __getitem__ __setitem__ __telitem__

    用于索引操作,如字典。以上分别表示获取,设置、删除数据

    __new__

    代码如下:

    1 class Foo(object):
    2     def __init__(self,name):
    3         self.name = name
    4 
    5 f = Foo("dean")
    6 print(type(f))
    7 
    8 print((type(Foo)))

    在上述代码中f是通过Foo实例化的对象,其实不仅f是一个对象,Foo类本身也是一个对象,因为在python中一切事物都是对象

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/__new__.py
    2 <class '__main__.Foo'>
    3 <class 'type'>
    4 
    5 Process finished with exit code 0

    上面的输出同样表示了:

    <class ‘__main__.Foo’>表示f对象由Foo类创建

    <class 'type'> 表示Foo类对象由type类创建

     

    所以从上面也可以得出f对象时Foo类的一个实例,Foo类对象时type类的一个实例,即Foo类对象时通过type类构造方法创建的

    所以创建类就可以有两种方法:

    普通方法

    1 class Foo(object):
    2     def func(self):
    3         print("hello dean")

    特殊方法

    1 def func(self):
    2     print("hello dean")
    3 Foo = type('Foo',(object,),{'talk':func})
    4 f = Foo()
    5 f.talk()
    6 print(type(Foo))

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/__new__.py
    2 hello dean
    3 <class 'type'>
    4 
    5 Process finished with exit code 0

    从这里也可以看出type就是类的类,所有的类都是通过type创建的

    将上述代码进行修改:

     1 def func(self):
     2     print("hello dean")
     3     
     4 def __init(self ,name,age):
     5     self.name = name
     6     self.age = age
     7 Foo = type('Foo',(object,),{'talk':func,
     8                             '__init__':__init})
     9 f = Foo("dean",23)
    10 print(f.name)
    11 print(f.age)
    12 f.talk()
    13 print(type(Foo))

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/__new__.py
    2 dean
    3 23
    4 hello dean
    5 <class 'type'>
    6 
    7 Process finished with exit code 0

    5、 反射

    getattr(obj,name_str)判断一个对象obj里是否有对应name_str的字符串的方法映射

    getattr(obj,name_str) 根据字符串去获取obj对象里的对应的方法的内存地址

    代码例子:

     1 class Dog(object):
     2     def __init__(self,name):
     3         self.name = name
     4     
     5     def eat(self):
     6         print("%s is eating..." %self.name)
     7 
     8 
     9 d = Dog("dean")
    10 choice = input(">>>:").strip()
    11 #
    12 # print(hasattr(d,choice))
    13 # print(getattr(d,choice))
    14 #
    15 # getattr(d,choice)()
    16 if hasattr(d,choice):
    17     func = getattr(d,choice)
    18     func()

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/反射1.py
    2 >>>:eat
    3 dean is eating...
    4 
    5 Process finished with exit code 0

    如果输入的字符串对应的方法不存在的情况让添加外面的类:代码如下,

     1 def bulk(self):
     2         print("%s is yelling....." %self.name)
     3 
     4 class Dog(object):
     5     def __init__(self,name):
     6         self.name = name
     7 
     8     def eat(self):
     9         print("%s is eating..." %self.name)
    10 
    11 
    12 d = Dog("dean")
    13 choice = input(">>>:").strip()
    14 
    15 if hasattr(d,choice):
    16         func = getattr(d,choice)
    17 func()
    18 else:
    19         setattr(d,choice,bulk)
    20         d.talk(d)

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/反射1.py
    2 >>>:talk
    3 dean is yelling.....
    4 
    5 Process finished with exit code 0

    setattr(obj,’y’,z) 相当于x.y = v

    代码例子:

    1 if hasattr(d,choice):
    2     func = getattr(d,choice)
    3     func()
    4 else:
    5     setattr(d,choice,22)
    6     print(getattr(d,choice))

    删除是delattr(d,choice)

    6、异常处理

    语法:

    1 try:
    2         pass
    3 except Exception as e:
    4         pass

    一个简单的例子:

    1 name =[1,2,3]
    2 
    3 try:
    4         name[4]
    5 except IndexError as e:
    6         print(e)

    如果想要同时抓多个错误的方法:

    1 try:
    2         code
    3 except(Error1,Error2) as e:
    4         print(e)

    如果想要一次性抓住所有错误可以用Exceptions(一般不用,无法定位错误,但是一般放到最后面,用于提示未知错误):

    1 name =[1,2,3]
    2 
    3 try:
    4         name[4]
    5 except Exceptions e:
    6         print(e)

    else 表示一切正常

    finally 表示不管有没有错都执行

    一些常见的异常:

     1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
     2 IOError 输入/输出异常;基本上是无法打开文件
     3 ImportError 无法引入模块或包;基本上是路径问题或名称错误
     4 IndentationError 语法错误(的子类) ;代码没有正确对齐
     5 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
     6 KeyError 试图访问字典里不存在的键
     7 KeyboardInterrupt Ctrl+C被按下
     8 NameError 使用一个还未被赋予对象的变量
     9 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    10 TypeError 传入对象类型与要求的不符合
    11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    12 导致你以为正在访问它
    13 ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    自定义异常代码例子:

     1 class myerror(Exception):
     2         def __init__(self, msg):
     3             self.message = msg
     4 
     5 try:
     6         name = []
     7         name = [3]
     8         raise myerror('我的异常')
     9 except myerror as e:
    10         print(e)

    运行结果如下:

    1 D:python35python.exe D:/python培训/s14/day7/自定义异常.py
    2 我的异常
    3 
    4 Process finished with exit code 0

    7、 socket编程

    一个简单的例子:

    服务端:

     1 import socket
     2 server = socket.socket()
     3 server.bind(('127.0.0.1',6969)) #绑定要监听的端口
     4 server.listen()#监听
     5 
     6 print("我要开始等电话了")
     7 #conn就是客户端连过来而在服务器端为其生成的一个连接实例
     8 conn,addr = server.accept()#等待电话打来
     9 
    10 print("电话来了")
    11 
    12 data = conn.recv(1024)
    13 print("recv:",data)
    14 conn.send(data.upper())
    15 
    16 server.close()

    客户端:

     1 import socket
     2 
     3 client = socket.socket()
     4 client.connect(('127.0.0.1',6969))
     5 
     6 client.send(b"Hello world")
     7 data = client.recv(1204)
     8 print("recv:",data)
     9 
    10 client.close()

    先运行服务端,在运行客户端,结果如下:

     1 D:python35python.exe D:/python培训/s14/day7/socket_server1.py
     2 我要开始等电话了
     3 电话来了
     4 recv: b'Hello world'
     5 
     6 Process finished with exit code 0
     7 D:python35python.exe D:/python培训/s14/day7/socket_client1.py
     8 recv: b'HELLO WORLD'
     9 
    10 Process finished with exit code 0

    将上述代码进行改进:

    服务端:

     1 import socket
     2 server = socket.socket()
     3 server.bind(('127.0.0.1',6969)) #绑定要监听的端口
     4 server.listen()#监听
     5 
     6 print("我要开始等电话了")
     7 while True:
     8     # conn就是客户端连过来而在服务器端为其生成的一个连接实例
     9     conn, addr = server.accept()  # 等待电话打来
    10     print("电话来了")
    11     while True:
    12         data = conn.recv(1024)
    13         print("recv:",data)
    14         if not data:
    15             print("client has lost....")
    16             break
    17         conn.send(data.upper())
    18 server.close()

    客户端:

     1 import socket
     2 
     3 client = socket.socket()
     4 client.connect(('127.0.0.1',6969))
     5 while True:
     6         msg = input(">>:").strip()
     7         client.send(msg.encode("utf-8"))
     8         data = client.recv(1204)
     9         print("recv:",data.decode())
    10 
    11 client.close()

    上述代码改进后可以在客户端断开后,服务端不会进入死循环没如果这个时候有新的客户端进入,可以继续通讯

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    23-10 条件查询
    22-9 聚合函数
    关系抽取snowball
    关系抽取bootstrap
    NER
    GPT
    因果卷积 空洞卷积
    XL-NET
    transoformer-XL
    transoformer
  • 原文地址:https://www.cnblogs.com/zhaof/p/5849764.html
Copyright © 2011-2022 走看看