类和实例的区别与联系
主要是对类和类的实例做一个区别,主要以代码演示为准
# -*- coding: utf-8 -*-
class student:
name = '我是24k'
_fname = '我是_24k'
__pname = '我是__24k'
# def __new__(cls, *args, **kwargs):
# if not hasattr(cls, '_isinstance'):
# cls._instance = super(student, cls).__new__(cls)
# return cls._instance
def __call__(self, *args, **kwargs):
print('你调用了我__call__')
def __init__(self):
print(self.name) #类的实例可以调用类的属性
print(self._fname) #类的实例可以调用类的属性
print(self.__pname) #类的实例可以调用类的属性
self.age = 10
self._fage = 'f10'
self.__page = 'p10'
def __str__(self):
return '调用了__str__内置类方法'
def __repr__(self):
return '调用了__repr__内置类方法'
def __A(self):
print('我是student的私有方法')
def threasd(self):
self.__A()
def _ac(self):
print('_ac是类的非完全私有方法')
@property #方法变成属性执行
def page(self):
return self.__page
#类实例化成对象
"""
类的实例调用实例的方法
"""
stu = student() #初始化时类的实例可以调用类的属性和私有属性
#实例调用实例的公共方法
stu.threasd()
#实例调用实例的非私有方法
stu._ac()
#实例调用实例的私有方法 ----不能直接调用,必须调用公共方法才能调用类的私有方法
# stu.__A()
"""
类的实例调用实例的属性
"""
print(stu.age)
print(stu._fage)
# print(stu.__page) #----不能直接调用,必须调用公共方法才能调用类的私有方法
print(stu.page)
#isinstance()方法 返回值是一个bool类型
# isinstance(object, classinfo)
# object: 实例对象
# classinfo: 可以是直接或间接类名、基本类型或者由它们组成的元组。
# isinstance (a,(str,int,list))
# isinstance(a, str)
# isinstance (a,int)
# isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
# isinstance() 与 type() 区别:
# type() 不会认为子类是一种父类类型,不考虑继承关系。
# isinstance() 会认为子类是一种父类类型,考虑继承关系。
# 如果要判断两个类型是否相同推荐使用 isinstance()。
#前后双下滑线方法是python自己定义出来,供自己调用的。这些方法会在特定的条件下被触发执行。下面是常用的一些前后双下划线方法。
#首先如果类中不存在这两个特殊方法,那么打印类的实例会返回一个内存地址
#__str__和__repr__的区别是调用时机不同,相同点都是对类到字符串的转换
# __str__ 当将对象转换成字符串时会执行
#解释:对一个类实例化之后直接打印就会调用这个方法,如下:
# print(stu)
# __repr__ 当将对象转换成字符串时会执行
#查看对象的时候调用__repr__方法,如:命令行直接stu
# 小结:
# * 我们可以使用 __str__ 和 __repr__ 方法定义类到字符串的转化方式,而不需要手动打印某些属性或是添加额外的方法。
# * 一般来说,__str__ 的返回结果在于强可读性,而 __repr__ 的返回结果在于准确性。
# * 我们至少需要添加一个 __repr__ 方法来保证类到字符串的自定义转化的有效性,__str__ 是可选的。因为默认情况下,在需要却找不到 __str__ 方法的时候,会自动调用 __repr__ 方法。
# __init__ 初始化方法,为对象变量赋值
# __new__ 构造方法,创建一个对象
print(type(stu))
print(type(stu))
print(type(stu))
# __call__ 在对象后面加括号会执行该方法
#使类的实例变得可调用
stu() # 你调用了我__call__
# __iter__ 类内部定义了该方法,对象就变成了可迭代对象
# __add__ 当两个对象使用+号会调用该方法
# __enter__和__exit__ 上下文管理
判断类中有无属性或者方法的三大方法: hasattr getattr setattr
先申明类不能拥有实例的属性,但实例可以使用类的属性和方法
print(hasattr(stu, 'age')) #True 此处应该注意你的参数是类还是实例
print(hasattr(stu, '_fname')) #True
print(hasattr(student, 'age')) #Flase
print(hasattr(student, 'name')) #True
getattr -------获取属性的命令格式
# getattr(object, name[, default])
解释:
获取object对象的属性的值,如果存在则返回属性值,如果不存在分为两种情况,一种是没有default参数时,会直接报错;给定了default参数,若对象本身没有name属性,则会返回给定的default值;如果给定的属性name是对象的方法,则返回的是函数对象,需要调用函数对象来获得函数的返回值;调用的话就是函数对象后面加括号,如func之于func();
另外还需要注意,如果给定的方法func()是实例函数,则不能写getattr(A, ‘func’)(),因为fun()是实例函数的话,是不能用A类对象来调用的,应该写成getattr(A(), ‘func’)();实例函数和类函数的区别可以简单的理解一下,实例函数定义时,直接def func(self):,这样定义的函数只能是将类实例化后,用类的实例化对象来调用;而类函数定义时,需要用@classmethod来装饰,函数默认的参数一般是cls,类函数可以通过类对象来直接调用,而不需要对类进行实例化;
setattr------设置属性值
setattr(object, name, value)
解释:
给object对象的name属性赋值value,如果对象原本存在给定的属性name,则setattr会更改属性的值为给定的value;如果对象原本不存在属性name,setattr会在对象中创建属性,并赋值为给定的value;
isinstance()方法
#isinstance()方法 返回值是一个bool类型
isinstance(object, classinfo)
object: 实例对象
classinfo: 可以是直接或间接类名、基本类型或者由它们组成的元组。
isinstance (a,(str,int,list))
isinstance(a, str)
isinstance (a,int)
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
#前后双下滑线方法是python自己定义出来,供自己调用的。这些方法会在特定的条件下被触发执行。下面是常用的一些前后双下划线方法。例如:
__str__ __repr__ 定义类到字符串的转换方式
__init__ __new__ 创建类和类的实例初始化
__call__ 类的实例可以直接调用
__iter__ __next__ 迭代器定义
__add__
__enter__ __exit__
str repr 定义类到字符串的转换方式
首先如果类中不存在这两个特殊方法,那么打印类的实例会返回一个内存地址
__str__和__repr__的区别是调用时机不同,相同点都是对类到字符串的转换
str 当将对象转换成字符串时会执行
解释:对一个类实例化之后直接打印就会调用这个方法,如下:
print(stu)
repr 当将对象转换成字符串时会执行
查看对象的时候调用__repr__方法,如:命令行直接stu
小结:
- 我们可以使用 str 和 repr 方法定义类到字符串的转化方式,而不需要手动打印某些属性或是添加额外的方法。
- 一般来说,str 的返回结果在于强可读性,而 repr 的返回结果在于准确性。
- 我们至少需要添加一个 repr 方法来保证类到字符串的自定义转化的有效性,str 是可选的。因为默认情况下,在需要却找不到 str 方法的时候,会自动调用 repr 方法。
init new
init 初始化方法,为对象变量赋值
new 构造方法,创建一个对象
print(type(stu))
print(type(stu))
print(type(stu))
call 在对象后加()就会他当作方法执行
使类的实例百年的可调用
stu()
#你调用了我__call__
iter 和 next
class test():
def __init__(self, data=1):
self.data = 1
def __iter__(self):
return self
def __next__(self):
if self.data > 5:
raise StopIteration
else:
self.data += 1
return self.data
for i in test(2):
print(i)
结果是2,3,4,5,6
add 当两个对象使用+号会调用该方法
enter__和__exit 上下文管理
class socket_01:
def __init__(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(('127.0.0.1', 8888))
self.socket.listen(5)
def __enter__(self):
print('server starting ...')
return self.socket
def __exit__(self, exc_type, exc_val, exc_tb):
print('执行__exit__方法')
self.socket.close()
调用
with socket_01() as socket_revc:
while True:
conn, addr = socket_revc.accept()
msg = conn.recv(1024).decode('utf-8')
print('recieve from {}:{}'.format(*(addr, msg)))
# conn.send(('recieve your msg:{}'.format(msg)).encode('utf-8'))