# class 定义
class My_class(object):
# 类属性,所有实例共有,优先级低于实例属性,只能通过My_class.count修改,修改后该类的其它实力和子类都会同步变化。
# stu.count=1只是再stu下新建一个高优先级的count=1的属性,对My_class.count无影响。
# del stu.count 后My_class.count==stu.count
# 实例属性属于各个实例所有,互不干扰;
# 类属性属于类所有,所有实例共享一个属性;
# 不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
count = -1
# 特殊的__slots__变量,来限制该class实例能添加的属性,
# 注意私有属性的写法,class方法不必写出,但通过类实例加入方法要写入,
# 且slots会对类属性设为只读,并且slots对继承的子类是不起作用的.
# __slots__ = ('__name', '__age','__score','args','kw','gender','set_gender','param')
# 初始化方法
def __init__(self, name, score, age=21, *args, **kwargs):
# 实例属性
self.__name = name
self.__score = score
self.__age = age
self.args = args
self.kw = kwargs
self.index = 0
# get/set访问私有变量。
def set(self, name, score, age):
self.__name = name
self.__score = score
self.__age = age
def get(self):
return [self.__name, self.__score, self.__age]
def print_score(self):
print('name:%s,score:%s,age:%s,args:%s,kwargs:%s' % (self.__name, self.__score, self.__age, self.args, self.kw))
# 简化get/set ,可通过stu.name实现访问/修改__name功能。
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
# 只定义get,__age就变为只读属性。
@property
def age(self):
return self.__age
# 实现len(stu)
def __len__(self):
return len(self.args)
# toString
def __str__(self):
return 'name:%s,score:%s,age:%s,args:%s,kwargs:%s' % (self.__name, self.__score, self.__age, self.args, self.kw)
__repr__ = __str__
# 实现遍历就必须实现一个__iter__()方法,该方法返回一个迭代对象,
# 然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,
# 直到遇到StopIteration错误时退出循环。
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.args[0]):
raise StopIteration
else:
self.index = self.index + 1
return self.args[0][self.index - 1]
# 下标访问
def __getitem__(self, index):
if isinstance(index, slice):
start = index.start
stop = index.stop
step = index.step
return self.args[0][start:step:stop]
else:
return self.args[0][index]
# 当调用不存在的属性时,Python解释器会试图调用__getattr__(self, name)来尝试获得属性,
# 只有在没有找到属性的情况下,才调用__getattr__,已有的属性,不会在__getattr__中查找。
def __getattr__(self, name):
if name == 'weight':
return 68
# 可以实现针对完全动态的情况作调用,如网站地址。
# class Chain(object):
#
# def __init__(self, path=''):
# self._path = path
#
# def __getattr__(self, path):
# return Chain('%s/%s' % (self._path, path))
# >>Chain().status.user.timeline.list
# '/status/user/timeline/list'
# 实现直接对实例进行调用stu(args)
def __call__(self, *args, **kwargs):
print('i\'m callable,%s,%s' % (args, kwargs))
def saySomething(self):
print('i\'m super class')
# 创建实例
stu = My_class('huang', 88, 33, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], key_0='vale_0', key_1='vale_1')
stu.print_score()
# 对实例变量绑定任何数据
stu.gender = 'male'
print(stu.gender)
# 对实例绑定方法,只对该实例起作用
def set_gender(self, gender):
self.gender = gender
from types import MethodType
stu.set_gender = MethodType(set_gender, stu)
stu.set_gender('female')
print(stu.gender)
# 对类绑定方法,对该类所有实例起作用
My_class.set_gender = set_gender
foo = My_class('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')
foo.set_gender('female')
print(foo.gender)
# 访问修改私有属性
print(stu.get())
stu.set('hu', 98, 20)
print(stu.get())
# stu.__name 无法访问,但可通过 _classname__propertyname 强制访问私有变量,不建议这么做。
# stu._My_class__name='qiang'
# print(stu._My_class__name)
# 子类
class Subclass(My_class):
# 复写父类方法
def saySomething(self):
# 子类调用父类方法
# super().saySomething
print('i\'m subclass')
sub_stu = Subclass('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')
sub_stu.print_score()
stu.saySomething()
sub_stu.saySomething()
# 实例与继承类关系
print(isinstance(stu, My_class),
isinstance(sub_stu, My_class),
isinstance(stu, Subclass)
)
# 有saysomething功能的任何类
class Other_class(object):
def saySomething(self):
print('i\'m other class')
others = Other_class()
# 继承与多态,不管实现只管调用。
def say_twice(stu):
stu.saySomething()
say_twice(stu)
say_twice(sub_stu)
# 鸭子类型,不管他是否是鸭子,他的行为像鸭子就行。
say_twice(others)
import types
# 实例类型判断
print(type(123) == type(456),
type(123) == int,
type('abc') == type('123'),
type('abc') == str,
type('abc') == type(123))
print(
type(say_twice) == types.FunctionType,
type(abs) == types.BuiltinFunctionType,
type(lambda x: x) == types.LambdaType,
type((x for x in range(10))) == types.GeneratorType,
)
print(
isinstance('a', str),
isinstance(123, int),
isinstance(b'a', bytes)
)
# 判断[1,2,3]是否是list或者 tuple
print(isinstance([1, 2, 3], (list, tuple)))
# 获得stu所有的属性与方法
print(dir(stu))
# 造作对象属性,只有在不知道对象信息的时候,我们才会去获取对象信息,优先使用object.property操作属性。
print(hasattr(stu, 'kw'), hasattr(stu, 'get'))
# none为可选参数,如果没有 kw属性才返回None
print(getattr(stu, 'kw', None))
# 获得函数,print_stu()==print_score()
print_stu = getattr(stu, 'print_score')
print_stu()
# 设置属性,等价于stu.param=20
setattr(stu, 'param', 20)
print(stu.param)
other_stu = My_class('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')
print(My_class.count, stu.count, sub_stu.count, other_stu.count)
stu.count = 1
# 只有stu.count 变化
print(My_class.count, stu.count, sub_stu.count, other_stu.count)
My_class.count = 2
# My_class 其它实例和子类都同步变化
print(My_class.count, stu.count, sub_stu.count, other_stu.count)
del stu.count
# stu.count值变回my_class.count值
print(My_class.count, stu.count, sub_stu.count, other_stu.count)
# 简化get/set实现读写
print(stu.name)
stu.name = 'huangqiang'
print(stu.get())
# 简化get实现只读
print(stu.age)
# stu.age=99999
# print(stu.get())
# 多重继承
class Anaimal(object):
def eat(self):
print('i can eat')
class Flyable(object):
def fly(self):
print('i can fly')
class Runable(object):
def run(self):
print('i can run')
class Dog(Anaimal, Runable):
pass
dog = Dog()
dog.eat()
dog.run()
# 定制类
# 获得长度
print(len(stu))
# toString
print(stu)
# 遍历对象
for i in stu:
print(i)
# 下标访问
print(stu[3])
print(stu[1:3:9])
# 动态属性
print(stu.weight)
# 直接调用对象
stu([1, 2, 3, 4], key='value')
print(callable(stu), callable(dog))
from enum import Enum
# Month类型的枚举类,可以直接使用Month.Jan来引用一个常量,或者枚举它的所有成员
# value属性则是自动赋给成员的int常量,默认从1开始计数.
Month = Enum('Mon', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
print(Month(1), Month.Jan, Month.Jan.value)
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
from enum import Enum, unique
# unique保证value唯一
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
print(Weekday(0), Weekday.Sun, Weekday.Sun.name, Weekday.Sun.value)
for name, member in Weekday.__members__.items():
print(name, '=>', member, ',', member.value)
原文:https://www.cnblogs.com/huangqiang97/p/11809641.html