day13python基础教学--面向对象进阶--元类、动态语言、__slots__变量

42 篇文章 0 订阅
39 篇文章 0 订阅

一、元类

1、在大多数编程语言中,类就是一组用来描述如何生成一个对象代码段。在Python中这一点仍然成立,但是Python中的类还远不止如此,类同样也是一种对象。使用关键字class,Python解释器子啊执行的时候就会 创建一个对象。
Python一切皆对象
Linux一切皆文件
2、类的本质是对象,于是可以对类做如下的操作:

  • 你可以将它赋值给一个变量
  • 也可以拷贝它
  • 可以增加属性
  • 可以将它作为函数参数进行传递
class Date(object):
    pass
# 1. 你可以将它赋值给一个变量
date = Date
print(date)
# 2.你可以拷⻉它
import  copy
date2 = copy.deepcopy(Date)
print(id(Date))
print(id(date2))
# 3.	 你可以为它增加属性
Date.year = 2019
print(Date.year)
# 4.	 你可以将它作为函数参数进行传递
def fun(cls):
    print(cls)
fun(Date)

3、type还有一种完全不同的功能,动态的创建类。
type可以接受一个类的描述作为参数,然后返回一个类
4、type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属 性的字典(名称和值))

  • Foo = type(‘Foo’,(),{‘chen’:20})
  • Foostudent = type(‘Foostudent’,(Foo,),{})

5、type创建带有方法的类
只需定义一个有着恰当签名的函数并将其作为属性赋值就可以了

  • 添加类方法
  • 添加实例方法
  • 添加静态方法
class Student(object):
    name = 'chen'

# 如何动态创建类? (基于元类创建的;)
MathStudent = type('MathStudent', (Student, ), {'country': 'china'})
print(MathStudent)
print(MathStudent.__bases__)
print(MathStudent.__dict__)
print(MathStudent.country)
print(MathStudent.name)

在python中,类也是对象,你可以动态的创建类。这就是当你使用关键字Class的时候python在幕后做的事情,而这就是通过元类来实现的。
6、元类就是用来创建类的“东西”。函数type实际上就是一个类。type就是Python在背后用来创建所有类的元类。
python的所有东西都是对象。而且它们都是从一个类创建而来,这个类就是type。
7、我们可以定义一个类的时候为其添加__metaclass__属性。python就会在类的定义中寻找__metaclass__属性,如果找到了,python就会用它来创建类Foo,如果没有找到,就会用内建的type来创建这个类。可以在__metaclass__中放置Django(ORM)

def upper_attr(cls_name, bases, attr):
    """

    :param cls_name: 类名称
    :param bases: 父类名称(元组)
    :param attr: 属性(字典)
    :return:
    """
    newAttr = {}
    for key, value in attr.items():
        newAttr[key.upper()] = value
    print(newAttr)
    return  type(cls_name, bases, newAttr)
# python3的写法
class Student(object, metaclass=upper_attr):
    # 自定义指定元类名称
    # python2:
    # __metaclass__ = upper_attr
    country = 'china'
    score = 100
s = Student()
# print(s.country)
print(s.COUNTRY)
print(s.SCORE)

元类本省而言:

  • 拦截类的创建
  • 修改类
  • 返回修改后的类

二、python是动态语言

1、 动态编程语言是 高级程序设计语言的一个类别,在计算机科学领域已被广泛应用。
它是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有
的函数可以被删除或是其他结构上的变化。动态语言目前非常具有活力。例如JavaScript便
是一个动态语言,除此之外如PHP、Ruby、Python等也都属于动态语言,而C、C++等语言则
不属于动态语言。

from prettytable import  PrettyTable
# 自省功能
# 判断;类里面是否包含指定的属性?
print(hasattr(PrettyTable, '__doc__'))
print(hasattr(PrettyTable, 'a'))
# 获取指定属性对应的内容;
print(getattr(PrettyTable, "__bases__"))
# print(getattr(PrettyTable, "a"))
# 设置指定的属性, 动态添加属性信息的
setattr(PrettyTable, 'a', 1)
print(getattr(PrettyTable, 'a'))
@staticmethod
def test():
    print("这是一个测试方法")
if hasattr(PrettyTable, 'test'):
    print(getattr(PrettyTable, 'test'))
else:
    print("正在动态添加方法:")
    setattr(PrettyTable, 'test', test)
    print(getattr(PrettyTable, 'test'))
    test = getattr(PrettyTable, 'test')  # 返回的时函数名
    test()
print(hasattr(PrettyTable, 'a'))
print("正在删除属性")
delattr(PrettyTable, 'a')
print(hasattr(PrettyTable, 'a'))

2、给类添加方法,是使用类名.方法名=xxx,那么给对象添加方法是对象.方法名=xxx

  • 对象.方法名=type.MethodType
  • 类名.方法名=方法名

3、删除的方法:

  • del 对象.属性名
  • delattr(对象, “属性名”)

三、__slots__变量

1、动态语言:可以在运行的过程中,修改代码
静态语言:编译时已经确定好代码,运行过程中不能修改
2、在定义class的时候,定义一个特殊的__slots_变量,来限制class实例能添加的属性
使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。

class MyCounter(object):
    # 限制属性的添加, 只能添加count和age;
    __slots__ = ('count', 'a','c')



print(hasattr(MyCounter, 'a'))

counter = MyCounter()
counter.a = 1
print(counter.a)
# counter.b = 2
# print(counter.b)---->报错
counter.c = 3
print(counter.c)
教学排课系统是一个典型的规划问题,可以使用clingo求解器来解决。下面是一个简单的教学排课系统的示例代码: ``` #const num_days = 5. #const num_slots = 4. #const num_courses = 3. % Define the domain day(1..num_days). slot(1..num_slots). course(1..num_courses). % Define the variables scheduled(C,D,S) :- course(C), day(D), slot(S). % Define the constraints :- scheduled(C,D,S), scheduled(C,D,S2), S != S2. % A course cannot be scheduled in two different slots at the same day :- scheduled(C,D,S), scheduled(C,D2,S), D != D2. % A course cannot be scheduled at two different days at the same slot % Define the preferences % Rule 1: First priority is to schedule the most important course in the first slot of the day 1 {scheduled(C,1,1) : course(C)} 1. :- scheduled(C,1,1), not scheduled(C,1,_). :- scheduled(C,D,S), C < 3, S > 1. % Rule 2: The last two slots of the day should be reserved for less important courses % Define the output format #show scheduled/3. ``` 在这个示例代码中,我们定义了三个常量:num_days、num_slots和num_courses,它们分别表示一周的天数、每天的时间段数和可安排的课程数量。我们还定义了三个变量:scheduled(C,D,S),它表示课程C安排在第D天的第S个时间段。接下来,我们定义了两个约束条件:一个是同一天同一课程不能安排在不同时间段,另一个是同一时间段同一课程不能安排在不同天。最后,我们定义了两个偏好规则:第一个规则是将最重要的课程安排在一天中的第一时间段,第二个规则是将不太重要的课程安排在一天中的最后两个时间段。最后我们定义了输出格式,即将所有安排输出。 使用clingo求解器求解这个问题非常简单。只需要将上述代码保存在一个文件中,然后在终端中运行以下命令: ``` clingo filename.lp ``` clingo将输出所有可行的课程安排方案。如果要限制输出结果的数量,可以使用clingo的-n选项,例如: ``` clingo filename.lp -n 10 ``` 这将输出前10个可行的安排方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值