一点提醒

首先在使用pickle读取load时,需要先把使用到的类import上,否则会报错.在pycharm中使用时不会报错,但在linux或者cmd时就会报错!必须import.

报错提示:

File "/Users/shane/PycharmProjects/Py_study/Base/S8/s9.py", line 8, in <module>
tt=pickle.load(open('test.pickle','rb'))
FileNotFoundError: [Errno 2] No such file or directory: 'test.pickle'

python编程时和Java C#一点区别

python中的函数参数可以是多种形态的.

Java和C#中,函数参数必须要指定类型;如果想向python中那样多种形态,要将参数指定为某类,参数可为类的子类或者派生类!

面向对象中的类成员

  1. 字段
  2. 方法
  3. 属性

字段

字段分为两种:

  • 普通字段
  • 静态字段

这里需要注意下的是,编程规范中,类名称一般需要首字母大写!

先来看段小程序吧:

class Province:
country='中国' #静态字段 def __init__(self,name):
self.name=name #普通字段 print(Province.country)
hn=Province('HN')
print(hn.country) #对象能访问,但一般不建议这么使用,建议使用类直接访问

普通字段我们使用的较多,一般是在构造方法时使用.

静态字段在代码加载时已经创建

字段 保存位置 规则
普通字段 保存在对象中 只能用对象去访问
静态字段 保存在类中(节约内存空间) 对象/类均可访问,但一般使用类访问,万不得已才使用对象访问)

方法

所有方法都属于类,类基本可以分为三中类型:

  • 普通方法
  • 静态方法
  • 类方法
方法 调用方式 特征
普通方法 由对象去调用执行,属于类 至少一个self,对象调用
静态方法 属于类,但通过类来调用,不依赖于任何对象,方法内部不需要对象封装的值时,可使用静态方法 任意参数,没有self,上面添加@staticmethod,类似装饰器的东东
类方法 静态方法的一种特殊形式,由类调用 至少一个cls参数,上面添加classmethod

来看两个例子吧:

静态方法:

class Province:
country='中国' #静态字段 def __init__(self,name):
self.name=name #普通字段 @staticmethod #静态方法
def show(arg1,arg2):
print(arg1,arg2) print(Province.country)
hn=Province('HN')
print(hn.country)
Province.show(123,456)

类方法:

class Province:
country='中国' #静态字段 def __init__(self,name):
self.name=name #普通字段 @staticmethod #静态方法
def show(arg1,arg2):
print(arg1,arg2) @classmethod
def f2(cls):
print(cls) Province.f2()

out:

<class '__main__.Province'>

属性

属性的特征:具有方法的写作形式,具有字段的访问形式.可取值,可设置,可删除.

先来看看属性是个什么东西吧:

class Pager:
def __init__(self,all_count):
self.all_count=all_count @property #定义属性
def all_pager(self):
a1,a2=divmod(self.all_count,10)
if a2==0:
return a1
else:
return a1+1 @all_pager.setter #赋值属性,将value赋值给方法的参数
def all_pager(self,value):
print(value) @all_pager.deleter #删除属性
def all_pager(self):
print('del all_pager') obj=Pager(101)
ret=obj.all_pager #不需要加括号
print(ret) obj.all_pager=102 del obj.all_pager

属性的基本使用

属性的定义和调用需要注意以下几点:

  • 定义时,在普通方法的基础上添加@property装饰器
  • 定义时,属性仅有一个self参数
  • 调用时,无需括号,obj.all_paper

属性存在的意义:访问属性时,可以制造出和访问字段完全相同的假象,由于属性是由方法变种而来,如果python中没有属性,完全可以由方法来替代.

属性的两种定义方式

python3中全都是新式类,有三种@property装饰方式:

  • @property
  • 方法名.setter
  • 方法名.deleter

其实就像上面的例子.

还有一种方式是静态字段方式.创建值为property的对象的静态字段.

来看个例子:

class Pager:
def __init__(self,name):
self.name=name def f1(self):
return 123 def f2(self,value):
print(value) def f3(self):
print('del....') foo=property(fget=f1,fset=f2,fdel=f3) obj=Pager(110)
ret=obj.foo #调用fget
print(ret) obj.foo=778 #调用fset del obj.foo #调用fdel

输出结果:

123
778
del....

其中fget,fset,fdel为默认参数.

类成员修饰符

每个类成员的修饰符有两种:

  • 公有成员:内部外部都能访问
  • 私有成员:字段前面加两个_,比如:__cc,只有自己的类内部能访问,继承的父类,子类均不能访问.

class Foo:
__cc='cccccccccc'
def __init__(self,name):
self.__name=name def f1(self):
print(Foo.__cc) def f2(self):
print(self.__name) @staticmethod
def __f3():
print('this is f3') @staticmethod
def f4():
Foo.__f3() # def obj=Foo('alex')
# obj.f1() #正确
# obj.f2() #正确
# obj.__f3() #报错
obj.f4() #正确 # Foo.__f3() #报错
Foo.f4()
print(obj._Foo__cc) #能显示,但不建议这么做,万不得已不要这么使用
# print(obj.name) #报错
成员 字段/方法/属性 访问方式
公有成员 静态 类可以访问;类内部可以访问;派生类中可以访问
公有成员 普通 对象可以访问;类内部可以访问;派生类中可以访问
私有成员 静态 仅类内部可以访问
私有成员 普通 仅类内部可以访问
print(obj._Foo__cc)

这种方式可以强制访问私有成员,但不符合规范...

类的特殊成员

python的类成员中有一部分特殊的存在.

  1. __doc__ 表示类的描述信息,即注释

  2. __module__ 表示当前操作的对象属于哪个模块

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

  4. __init__ 构造方法

  5. __del__ 析构方法,当对象在内存中被释放的瞬间执行(此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。)

  6. __call__ 对象后面加括号,触发执行,例如:

    class Foo:
    def __init__(self,name,age):
    self.name=name
    self.age=age def __call__(self, *args, **kwargs): #加括号执行
    print("__call__") def __str__(self):
    return '%s-%s'%(self.name,self.age) a=Foo('alex',19)
    a()

    out:

    __call__
    alex-18
    __call__
  7. __str__ 覆盖显示内存地址的内容,如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。

  8. __dict__ 类或对象中的所有成员,如果是类,返回的是对象的所有字段,如果是对象,返回所有成员,并且无论类或者对象,全部返回数据为字典类型.

    class Foo:
    def __init__(self,name,age):
    self.name=name
    self.age=age def __call__(self, *args, **kwargs): #加括号执行
    print("__call__") def __str__(self):
    return '%s-%s'%(self.name,self.age) a=Foo('alex',19)
    # a()
    # print(a)
    print(a.__dict__)
    print(Foo.__dict__)

    out:

    {'name': 'alex', 'age': 19}
    {'__doc__': None, '__str__': <function Foo.__str__ at 0x10127b7b8>, '__call__': <function Foo.__call__ at 0x10127b730>, '__init__': <function Foo.__init__ at 0x10127b6a8>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__dict__': <attribute '__dict__' of 'Foo' objects>}
    alex-18
    __call__
9. \_\_getitem__、\_\_setitem__、\_\_delitem__ 用于索引操作,对象后面加中括号"[]",将中括号中的参数传给item,来两个例子:

	```python
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age def __getitem__(self, item):
if type(item)==str:
print(798)
return 798 elif type(item)==slice:
print(item.start)
print(item.stop)
print(item.step) def __setitem__(self, key, value):
if type(key)==str:
print('setitem')
elif type(key)==slice and type(value)==list:
print(key.start)
print(key.stop)
print(key.step)
print(value) def __delitem__(self, key):
if type(key)==str:
print('delitem')
elif type(key)==slice:
print(key.start)
print(key.stop)
print(key.step) a=Foo('cc',23)
res=a[1:4:12]
print(res) a[1:4]=[2,3,4,5] del a[1:5]
```
输出: ```python
798
798
setitem
delitem
``` 10. \_\_getslice__、\_\_setslice__、\_\_delslice__ 用于分片操作,看个例子: ```python
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age def __getitem__(self, item):
if type(item)==str:
print(798)
return 798 elif type(item)==slice:
print(item.start)
print(item.stop)
print(item.step) def __setitem__(self, key, value):
if type(key)==str:
print('setitem')
elif type(key)==slice and type(value)==list:
print(key.start)
print(key.stop)
print(key.step)
print(value) def __delitem__(self, key):
if type(key)==str:
print('delitem')
elif type(key)==slice:
print(key.start)
print(key.stop)
print(key.step) a=Foo('cc',23)
res=a[1:4:12] #自动执行getslice
print(res) a[1:4]=[2,3,4,5] #自动执行setslice del a[1:5] #自动执行delslice
```
out: ```python
1
4
12
None
1
4
None
[2, 3, 4, 5]
1
5
None
```
11. \_\_iter__ 用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 \_\_iter__,如果对象想被迭代,就得用此方法. ```python
class Foo:
def __iter__(self):
yield 1
yield 2 a=Foo()
for item in a:
print(item)
``` out: ```python
1
2
```
###自己写一个有序字典
利用上面的知识,我们可以自己写一个有序字典: ```python
class Mydict(dict): def __init__(self):
self.li=[]
super(Mydict,self).__init__() def __setitem__(self, key, value):
self.li.append(key)
super(Mydict,self).__setitem__(key,value) def __str__(self):
temp_list=[]
for key in self.li:
value=self.get(key)
temp_list.append('"%s":%s'%(key,value))
temp_str='{'+','.join(temp_list)+'}'
return temp_str d=Mydict()
d['a']=111
d['b']=222
print(d)

输出:

{"a":111,"b":222}

其他相关

isinstance(obj,cls) 检查obj是否是cls创建的对象

issubclass(cls1,cls2) 检查cls1是否是cls2的子类

super(cls,self).func() 主动执行父类的方法,看个例子:

class c1:
def f1(self):
print('c1.f1') class c2(c1):
def f1(self):
super(c2,self).f1()
print('c2.f1') #如果想主动执行c2父类的f1(),可以这么写 a=c2()
a.f1()

out:

c1.f1
c2.f1

此方法一般用来在不改变原代码的基础上做修改时使用此类方法即可.

单例模式

总结上面的知识,我们写一个单例模式吧,顾名思义,单例模式就是此模式只能创建一个实例,第一次创建一个模式,如果第二次创建是,返回还是第一个创建的实例或者对象,看代码吧:

class Foo:
instance=None def __init__(self,name):
self.name=name @classmethod
def get_instance(cls,value): #一般没value
if cls.instance:
return cls.instance
else:
obj=cls(value) #一般设定死
cls.instance=obj
return obj obj1=Foo.get_instance('alex')
print(obj1)
obj2=Foo.get_instance('cc')
print(obj2)

输出:

<__main__.Foo object at 0x101a78ac8>
<__main__.Foo object at 0x101a78ac8>

python基础之面向对象(二)的更多相关文章

  1. 二十. Python基础(20)--面向对象的基础

    二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...

  2. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  3. 自学Python之路-Python基础+模块+面向对象+函数

    自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python    1.1 自学Python1.1-简介    1.2 自学Python1.2-环境的 ...

  4. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  5. python基础,函数,面向对象,模块练习

    ---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? #  [] {} () None 0 2,位和字节的关系? # ...

  6. python基础篇(二)

    PYTHON基础篇(二) if:else,缩进 A:if的基础格式和缩进 B:循环判断 C:range()函数和len()函数 D:break,contiue和pass语句 for,while循环 函 ...

  7. python基础扩展(二)

    python基础扩展(二) 常用操作 1.startswith(以什么开始) endswith(y)什么结束 s='taiWanw39dd' print(s.startswith('t')) #意思是 ...

  8. Day7 - Python基础7 面向对象编程进阶

    Python之路,Day7 - 面向对象编程进阶   本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...

  9. Python基础7 面向对象编程进阶

    本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 经典 ...

随机推荐

  1. uni-app之导航配置pages.json

    1.基础配置,各个页面都要在这里边引入. 2.基础配置,头部导航左右上脚的buttons设置. 3.如果没有权限展示底部导航的需求,可以直接在此文件配置底部导航.

  2. 获取历史K线数据的几个方法

    1.通过已有的股票交易软件下载数据,如果他们是开源结构的,就可以解析他们的K线数据. 2.在互联网上抓取数据 int iStockCode;CString strUrl; 通过OpenUrl.Read ...

  3. 修改DEDE文章标题长度,解决DEDE文章标题显示不全

    在用dede调用列表标题出来的时候,会发现标题文字字数显示不完全,那是因为dede默认标题出来长度是30个字符,为了让标题显示完整,要做以下修改! 进入后台–系统–系统设置–系统基本参数–其他选项–文 ...

  4. Windows 创建Raid

    Windows 常见raid有0.1和5,以下操作在虚拟机下模拟,学会这招在自己电脑做个raid也未尝不可啊~ 一.RAID 0 创建: 添加两块硬盘,联机并初始化(2T以下选MBR,以上选GPT) ...

  5. 013——C# chart控件时间作为X轴(附教程)

    (一)参考文献:C#之Chart控件系列教程——一 (二)下载地址:https://download.csdn.net/download/xiaoguoge11/11838944 (三)视频教程:ht ...

  6. sql server 游标的基本用法

    DECLARE @Id NVARCHAR(MAX) DECLARE @UserName NVARCHAR(MAX) DECLARE @Password NVARCHAR(MAX) DECLARE @N ...

  7. Linux系统出现hung_task_timeout_secs和blocked for more than 120 seconds的解决方法

    Linux系统出现系统没有响应. 在/var/log/message日志中出现大量的 “echo 0 > /proc/sys/kernel/hung_task_timeout_secs" ...

  8. 【.Net设计模式系列】工作单元(Unit Of Work)模式 ( 二 )

    回顾 在上一篇博客[.Net设计模式系列]仓储(Repository)模式 ( 一 ) 中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢 @横竖都溢 @ 浮云飞梦 2位兄台对博 ...

  9. Qt进程间通信

    Qt 提供了四种进程间通信的方式: 使用共享内存(shared memory)交互:这是 Qt 提供的一种各个平台均有支持的进程间交互的方式. TCP/IP:其基本思想就是将同一机器上面的两个进程一个 ...

  10. TensorFlow(十六):TensorFlow GPU准备

    一:安装cuda 下载地址 二:安装cuDNN 三:安装GPU版TensorFlow 注意:gpu版的TensorFlow打开tensorboard要使用:tensorboard --logdir C ...